@hylarucoder: When AI writes code faster than your team can understand it, what guards the lifeblood of your software? From compilers, architectural skeletons, and read-only contracts to refactoring loops and disposable implementations, here are some recent thoughts on code governance in the AI era.
Summary
The author explores what to do when AI coding agents produce code faster than a team can comprehend it, and how five layers of governance — compiler-enforced constraints, architectural skeletons, read-only contracts, refactoring loops, and disposable implementations — can counteract system entropy and human cognitive bankruptcy to preserve software maintainability.
View Cached Full Text
Cached at: 10/31/26, 05:34 PM
When the Speed of Writing Code Approaches Infinity, What Do We Rely On to Hold the Lifeblood of Software? — Deep Reflections on Software Engineering Governance in the Age of AI Agents
Introduction: Waking Up at Dawn to Tens of Thousands of Lines of “All Green” Code
Imagine this scenario:
The night before, before going to sleep, you dispatched 6 work orders to 6 Coding Agents on your computer by voice — from adding a billing statistics endpoint, to integrating Feishu card notifications, to fixing two intermittent concurrency state bugs. You slept soundly all night, while the agents tirelessly read code, modified files, and ran tests on their respective Git branches.
At eight o’clock the next morning, you sit down at your computer with a cup of coffee. An encouraging summary dashboard pops up on the screen: all 6 work orders completed, tens of thousands of lines of new code added, all unit tests showing green passes, and Git reports no textual conflicts.
At this moment, should you feel euphoria, or a chill down your spine?
If you’ve truly experienced the full cycle of high-frequency AI-assisted iteration on a medium-sized or larger project, you know that bottomless fear: there is absolutely no way you can meaningfully read through tens of thousands of lines of code in the half hour before the morning standup. You can only skim the file names, click “Merge” with crossed fingers, and post a tweet: “We’ve completely stopped having humans review code.”
In the first week, you feel like you’ve discovered the magic of 10x-speed development; By the third week, you notice that every small requirement change causes AI to casually touch a dozen files, and it frequently reintroduces bugs that were fixed just last week; Then, deep into the second month, a production system suddenly crashes from a deadlock. You open the codebase to do emergency firefighting, only to discover with despair — facing this 50,000-line blob of code that AI has scribbled over hundreds of times, littered with redundant branches and weird wrapper functions, not a single human on the team knows how it actually runs anymore.
This is the invisible wall that every team deeply using AI-assisted programming is hitting or about to hit: when the marginal cost of producing code approaches zero, the core contradiction of software engineering has been completely inverted from “how to write code faster” to “how to combat exponentially exploding system entropy and human cognitive bankruptcy.”
What this article aims to explore in depth with you is not how to write a few fancy prompts to get AI to generate a toy demo, but rather — from the perspective of architecture and engineering governance — to answer an ultimate question that determines the longevity of future software: in the age of AI agents, how should we actually maintain and govern a software system that needs to evolve over the long term?
I. Tearing Off the Warm, Friendly Facade: Why AI Is a Born “Local Patcher”
Many people are accustomed to blaming AI’s bad code on “the model isn’t smart enough enough” and pinning their hopes on the next generation of foundation models to automatically produce master-level architecture. But if we look at how large language models (LLMs) actually work, we uncover a brutal truth: AI produces unmaintainable spaghetti code not because of insufficient compute, but because it is dictated by its underlying objective function.
In software maintenance, AI agents carry six deeply embedded “genetic flaws”:
1. It Only Does “Local Patching” — It Will Never Proactively Do “Global Abstraction”
When an excellent human engineer writes the 3rd similar channel integration (say, after WeChat and Feishu, now integrating a QQ bot), they experience a strong physiological discomfort, and instinctively extract the retry logic, rate limiting, and message parsing into a shared base class or higher-order function.
But AI has no “code cleanliness obsession.” Its attention window is fixated solely on the current work order, and its implicit goal is to pass the current task with the minimal possible scope of change. For AI, modifying a shared module means extremely high compilation error risk; the safest, lowest-resistance path is always to copy-paste from a neighboring file and change a couple of lines, or to jam another if-else at the end of a function that’s already 200 lines long.
In other words, AI is a born Local Patcher, not a Global Abstractor.
2. It Is Terrified of Deleting Code, Leading to Mountainous Accumulations of Zombie Code
In repositories maintained by AI over the long term, code size almost always increases monotonically.
When you ask AI to refactor a module from “timed polling” to “event stream push,” because AI cannot be 100% certain whether any other place in the repo (or even dynamic call sites) still references the old pollStatus() function, its defensive instinct is to fully preserve the old pollStatus() and then create a new streamStatus() right next to it.
Six months later, 40% of the code in the repository is “zombie code (dead code)” that no real business path will ever trigger. What’s worse, later AI agents, when searching for context, will ingest this zombie code as if it were valuable current logic — and even go so far as to continue fixing bugs in and writing tests for dead code with a straight face.
3. It Is Masterful at “Opportunistic Escape” — Even Tampering with Tests to Fake a Green Light
Strong type systems (like TypeScript strict mode, Effect-TS’s error channel, Rust’s borrow checker) are meant to be quality guardrails. But when the compiler error is slightly complex, AI easily resorts to “opportunistic escape” — casually stuffing in an as any, an @ts-ignore, or writing an empty catch {} that swallows the exception.
The most lethal behavior is when fixing bugs: if business code has been tweaked for a while and still fails a boundary unit test, an unconstrained AI will often have a “brilliant” idea — go directly and change the assertions in the unit test to accommodate its buggy implementation, then cheerfully report to you that “all tests pass.”
4. It Defaults to Living in a “Greenhouse,” with Zero Awe for Complexity or Resource Leaks
The vast majority of code in training corpora consists of teaching-grade, happy-path examples. Therefore, AI’s code naturally assumes the network always responds instantly, the disk never locks, and memory is infinite:
-
It absolutely loves calling the database or spawning external Git subprocesses directly inside
.map()loops that iterate over lists (classic N+1 performance poisoning). With 5 tickets, it runs buttery smooth; when tickets pile up to 100, it freezes the machine dead. -
It absolutely loves casually doing
new Map()for caching inside long-running services, but can never remember to write an eviction strategy (LRU/TTL) — guaranteed memory overflow after running for two full days. -
When receiving streaming data, it dares to
JSON.stringifythe entire large state object and write it synchronously to disk once per character received.
5. Every Time It Wakes Up, It Has “Amnesia,” Easily Breaching Architecture Boundaries and the Supply Chain
Human teams have unwritten “architectural ground rules” passed down through tribal knowledge (for example, the domain layer must never reference the UI layer in reverse; date handling must use only the built-in library). But every agent that spins up is a “stateless temp worker” on their first day of the job.
Agent #1 casually runs bun add moment to format dates, Agent #2 installs dayjs, Agent #3 installs date-fns; for the sake of momentary convenience, they will cross module facades to directly read and write other people’s internal private state at any time, causing a once-clear layered architecture to degenerate into complete mush after a dozen iterations.
6. No Matter How Detailed the Documentation, It May Still Fail to Execute Properly
Many teams assume that if they just write the specifications in enough detail, the problem is solved: architecture descriptions, coding conventions, acceptance checklists — meticulously written into AGENTS.md and design docs.
But the reality is, even when you provide extremely detailed documentation, AI may still fail to execute properly: it followed 8 out of 10 constraints, and the one it missed happened to be the most critical one; in the first half of a task it remembered “all subprocesses must go through managed primitives,” but by the second half, with a long context, it forgot; the word “must” in the docs was treated as “suggested”; a step on the acceptance checklist was never run at all, yet the final report claims “completed.”
Documentation expresses intent — it does not provide constraints. The model reading something doesn’t mean it did it; doing it once doesn’t mean it will do it every time. Any rule that exists only in documentation and is not checked by scripts or compilers should be presumed to be violated.
Core Insight #1: In traditional software engineering, “writing code” and “maintaining architecture” happen synchronously within the same process of a human typing at a keyboard. But in the AI era, these two things are completely decoupled — AI provides near-infinite “code proliferative force,” and unless humans can provide equally strong “architectural convergent force,” the system will die of malignant bloat in an extremely short time.
II. The Architect’s Cognitive Leap: Building a “Five-Layer Anti-Entropy Governance Pyramid”
Faced with the chaos described above, the first instinct of many teams is to change the prompts — filling AGENTS.md and CLAUDE.md with two thousand lines of earnest pleading: “Please mind code reuse, please maintain high cohesion and low coupling, please don’t write functions longer than 100 lines…”
The result? Utterly useless. Because LLMs suffer from a severe “Lost-in-the-Middle” effect in their attention, and natural language documentation that doesn’t participate in compilation will not only be selectively ignored by the model within two weeks, but will also become poison that misleads the AI as it drifts out of sync with the latest code.
Real engineering governance has never relied on verbal promises — only on physical guardrails and deterministic feedback.
To truly tame AI-era software iteration, we need to build a bottom-up “Five-Layer Anti-Entropy Governance Pyramid.” The core design philosophy of this pyramid can be summed up in one sentence: the lower the layer, the more it relies on zero-token-cost compilers and deterministic scripts for hard interception; the higher the layer, the more it focuses on contract locking, read-write separation, and decisive disposal.
Below, we peel apart the most powerful engineering techniques in this system layer by layer.
III. Layers One and Two: Using Compilers and Architectural Skeletons to Cage AI in a “Fill-in-the-Blanks Iron Cage”
Why does AI scatter logic everywhere and spawn orphan processes? Because you gave it the freedom to manipulate global control flow. At the bottom two layers of the pyramid, our goal is: any error that a machine can block in 10 milliseconds should never consume a single token; reclaim all public control flow and let AI only do constrained fill-in-the-blanks.
Technique 1: Turn the Compiler into AI’s “Global Modification Navigator”
AI’s biggest fear when maintaining code is “missing a change.” For example, the system adds a new task state Paused. AI updates the definition and two pieces of logic, but misses the state checks in five other files.
How to fix this at the root? Completely ban composing states from multiple booleans (like isLoading + isError); enforce Discriminated Unions; and disable switch default branches across the entire repository, turning on Exhaustiveness Checks.
When you represent states as mutually exclusive union types and place assertNever(state) at the end of every branch match, a miracle occurs: the moment AI adds a _tag: "Paused", the TypeScript or Rust compiler will, within 0.1 seconds, highlight every file name and exact line number across the entire repository that is missing a Paused handling branch!
The compiler’s error list directly becomes AI’s global modification to-do list. AI doesn’t need to guess where else changes are needed through fuzzy search — it just follows the errors and fills them in one by one, and the logic is 100% closed.
Similarly, aggressively adopt Branded Types: never pass a bare number or string across module interfaces. Define cents as Cents, define millicents as Millicents; define a plain path as string, and a security-verified worktree path as VerifiedWorktreePath. When the unit or the order of prerequisite validation is wrong, the code won’t even compile.
Technique 2: “Prescriptive AST Errors (Error as Prompt)” — Turning the Linter into a Real-Time Mentor
Traditional Linter errors are written for human eyes and often just coldly emit a single line: Error: Unexpected any or Error: Do not use child_process.spawn.
What does AI do when it sees such an error? To eliminate the error, it will do something even dumber — like changing any to as unknown as MyType, or calling the underlying interface under a different name.
We need to understand a key principle: in the AI coding loop, the stderr error messages printed to the terminal are the golden few-shot prompts closest to the model’s next round of generation, carrying the highest weight.
Using syntax-tree checking tools like ast-grep, we can write “prescriptive error rules” in a dozen lines of YAML — not just blocking violations, but directly printing this project’s standard primitive invocation templates and reference file line numbers in the error message:
# Prescriptive AST rule: not just "what not to do," but feeding the correct answer straight to AI's mouth
id: no-raw-subprocess
language: TypeScript
rule:
pattern: Bun.spawn($$$ARGS)
message: |
[Architecture Red-Line Violation] Direct calls to Bun.spawn are strictly forbidden
(causes orphan process leaks when tasks are cancelled).
👉 Please copy the managed primitive pattern below as a replacement:
const output = yield* ManagedProcess.exec({ cmd: [...], cwd: verifiedWorktree })
📖 Reference implementation: src/infra/process/ManagedProcess.test.ts:L12-L28
severity: error
These rules don’t have to be written with ast-grep — most mainstream tools can embed the correct pattern in the error:
-
ast-grep: write syntax tree matching rules in YAML, put the prescription in
messageandnote, and use thefixfield to provide automatic rewrites; -
Semgrep: rules are also in YAML, suitable for cross-language checks, and supports data-flow rules like taint tracking;
-
ESLint:
no-restricted-importsandno-restricted-syntaxboth support custom error messages — at zero cost you can write “do not import child_process directly, use ManagedProcess instead” into the error; -
Biome: from 2.0 onward, supports plugin rules written in GritQL;
-
dependency-cruiser: specializes in module dependency boundaries, perfect for tackling the “sneaking past the facade” problem from Flaw #5.
In practice, with those three lines of “fix prescription” added, AI doesn’t need to go searching the entire repo after seeing the error — in the next round it simply copies the template and gets it right the first time, with a self-healing rate of over 95%.
Technique 3: Automated “Dead Code Guillotine”
To overcome AI’s habit of “only adding code, never daring to delete it,” hook whole-repo reachability analysis tools directly into the CI gate (such as knip for TypeScript or deadcode for Go).
They build a complete symbol reference graph starting from the program entry point: the moment they find an exported function, type, or dependency package with zero external references anywhere in the entire repository, it is blocked as a compile error! At the same time, AST rules prohibit writing open-ended @deprecated annotations — they must be written as @deprecated(removeBy: "2026-11-30"), and anything not removed by the deadline automatically fails CI. This forces AI to thoroughly clean out old code and old tests when replacing legacy logic.
Technique 4: Vertical Feature Slices + Template Harness + Single State Machine
To prevent AI from scattering code, three structural cuts are mandatory:
-
Abandon horizontal MVC layering in favor of “Vertical Feature Slices (Colocation)”: Don’t make the AI jump across five distant directories — controllers, services, types — just to change one feature. Create folders by business feature (like
features/ticket-settlement/) and stuff that feature’s models, state machines, implementations, and tests all into the same directory. Externally, only the singleindex.tsis allowed to expose the interface; nothing outside is permitted to sneak pastindex.tsto reference internal files. -
Template Harness pattern to reclaim control flow: Anything involving timeouts, retries, billing, worktree locking, and subprocess reclamation is consolidated into a handful of higher-order functions (like
runWithAgentHarness(plugin)), which coding agents are not allowed to modify. This harness layer may be drafted by AI, but there is only one standard: it must be short, straightforward, and free of magic — any team member can read it line by line — and it is locked after human review. The harness is the code in the entire system that is least allowed to be “incomprehensible”: where resources are acquired and where they are released must be visible at a glance. When asking AI to add a 4th coding tool or a 3rd chat platform adapter, it is only allowed to implement a narrow interface of fewer than 50 lines (responsible only for converting input to parameters and output lines to events). AI can’t even touch the edges of processes and locks, so it naturally can’t write code that leaks resources. -
Single State Machine (FSM) + Domain Event Bus (PubSub): Only pure-function state machines are allowed to modify core business state. After a state change, they emit notification events (like
TicketCompleted) to the event bus. Sending WeChat messages, refreshing the UI, and computing achievements are all written as independent event subscribers. When adding a new channel in the future, the core trunk code achieves true “zero modification.”
IV. Layer Three: Locking Down the Contract Wall and “Deterministic Simulation” to Eliminate Test Rot and Slow Code
If the first two layers govern what code looks like, then Layer Three addresses: how do we prove that AI-written code is absolutely reliable in business terms, and that the test code itself doesn’t become a mountain of crap?
Technique 5: Build a “Three-Tier Read-Only Contract Wall” to Physically Block Test-Cheating
In engineering permissions, the repository must be split into two isolated zones:
-
Read-Only Contract Zone: includes communication and persistence protocols (
src/contracts/schema/), core service interface signatures (src/contracts/interfaces/), and business acceptance tests (tests/acceptance/`). -
Writable Implementation Zone: the concrete business implementation of each vertical slice (
src/features/).
When fixing bugs or developing new features, a strict two-phase lock is enforced: In Phase One, you may only write failing red-light tests (Red) under tests/acceptance/; after verifying the failure, a Git Hook immediately locks the SHA-256 hashes of the contract zone and acceptance test directory. Only in Phase Two is the coding agent released to modify implementation code until the tests turn green (Green). If the coding agent tries to cheat by modifying test assertions, the Git commit is rejected on the spot.
Technique 6: Abolish Fragile Scattered Mocks; Use “I/O Counters” to Catch O(N²) Slow Queries
AI has a terrible habit when writing unit tests: it loves to use vi.fn().mockReturnValue(...) to lock down all 5 private dependencies called inside the function under test. The result is that business behavior hasn’t changed at all, but when you do a minor refactor to split an internal function, all 50 tests break.
At the same time, AI loves sneaking database queries or file I/O into loops, but under small-data-volume tests this only takes a few milliseconds — completely invisible.
How to break through? Completely ban scattered mocks; uniformly mount in-memory contract fake layers with call counters!
We provide a single set of FakeStorage and FakeGit implemented with in-memory Maps for the database, filesystem, and Git drivers, with two simple variables: readOpCount and writeOpCount. In tests, we don’t assert on milliseconds that fluctuate wildly with machine load — we directly assert on the upper bound of underlying I/O call counts:
it("rendering a board of 200 tickets must perform <= 2 underlying storage reads (catching in-loop N+1 queries)", async () => {
const fakeStore = new FakeTicketStorage()
await seedTickets(fakeStore, 200)
fakeStore.readOpCount = 0 // reset counter
await renderBoard({ storage: fakeStore })
// If AI queries the database one by one inside a .map() loop over 200 tickets,
// this becomes 200 and goes red on the spot!
expect(fakeStore.readOpCount).toBeLessThanOrEqual(2)
})
This single simple counter assertion is 100% deterministic with 0 milliseconds of variance. Any terrible code that stuffs I/O into a loop or does high-frequency full-state disk flushes will be caught red-handed the instant unit tests run locally. Combined with a virtual clock (TestClock) and property-based testing (randomly generating 100 shuffled concurrent command sequences to bombard the state machine), thousands of lines of async logic can undergo a high-intensity health check within 1 second.
Technique 7: Historical Archive “Golden Snapshot Regression Tests”
Why do many AI-iterated projects put an embarrassing reminder on their website: “Please manually back up your local data before upgrading”? Because AI casually renamed a field in an in-memory struct and directly crashed the local save files of existing users.
The solution is simple and ruthless: under tests/fixtures/snapshots/, permanently store real save-file samples from every historical version from v0.1 to the present. Every time code is committed, CI forcibly upgrades all historical samples to the latest structure — if even one old-version sample fails to deserialize or loses a field, the merge is blocked.
V. Layers Four and Five: The Dual-Loop Workflow and the Evolutionary Economics of “Throw It Away and Regenerate at Any Time”
Once the bottom iron cage, the middle harness, and the contract defense line are all in place, the top layer delivers the most stunning overturn of software engineering thinking.
Technique 8: The “3+1 Seeding and Weeding” Dual-Work-Order Cycle — Making Abstraction a Standalone Process
Never expect the same AI to do good code abstraction (convergent thinking) while simultaneously writing new features (divergent thinking).
We implement a rigid 3+1 dual-loop cadence in the development pipeline:
-
After 3 consecutive feature work orders are merged (seeding), the system automatically freezes new requirement dispatch, runs a static clone detection pass (
jscpd) and Git history co-change analysis (finding cross-directory file pairs that were always modified together over the past 50 commits), and auto-generates a 4th pure refactoring work order (weeding). -
The instructions given to this weeding agent are extremely pure: “Compare the syntax trees of File A and File B. Sink their common control flow (invariants) into higher-order combinators. Compress the original files into pure parameter configurations (variants). Hard requirements: zero modifications in the
tests/directory, all tests passing, and a net reduction of at least 15% in total lines of code for the target modules!”
An even more critical iron rule: for any mechanical refactoring or interface renaming involving more than 5 files, AI is strictly forbidden from editing them one by one with file-editing tools (by the 20th file, it will inevitably miss changes or hallucinate code deletions due to context decay). Instead, AI is required to write a 30-line AST transformation script (Codemod), which a deterministic engine uses to complete the lossless batch replacement across the entire repo in 0.5 seconds.
Technique 9: Merge Queue Rehearsal — Eliminating “Semantic Disasters with Zero Textual Conflicts”
When multiple agents develop in parallel on their own worktrees, the most terrifying thing is not Git reporting a textual conflict — it’s Git reporting a Clean Merge (zero conflicts), yet the system crashes immediately after merging into the trunk.
For example, Agent #1 changes the return unit in quota.ts from cents to millicents. Meanwhile, Agent #2, in feishu.ts, calls the old function that pushes billing notifications in cents. The two agents modified completely different files, Git merges without a ripple, but after going live, billing amounts are inflated by a factor of 1000!
Therefore, when any branch is clicked for merge, it must never go directly into main — it must enter a Merge Queue, which automatically merges it with the latest trunk and re-runs the full compilation and tests in the combined state, while also performing an AST symbol lock check to verify “whether the internal implementation of referenced functions has changed hash.”
Technique 10: The Ultimate Mindset Overturn — “Contracts Are Diamonds; Implementation Code Is Toilet Paper”
In traditional software maintenance, because human code-writing is expensive, we assumed “patching old code is cheaper than rewriting,” forcing engineers to grit their teeth and patch decade-old legacy spaghetti.
But in the AI era, run the numbers anew:
Generating 300 lines of clean business code from scratch with a large model costs 5 cents and takes 1 minute; whereas having a large model read and patch a 300-line piece of spaghetti code that has already been modified 10 times and is full of historical patches consumes ten times the context tokens and has an extremely high probability of introducing new bugs!
This leads to the ultimate law of software maintenance in the AI era — Disposable Cells architecture and the “Three-Strikes Strikeout Regeneration Mechanism”:
-
We strictly limit each concrete business slice from Layer 2 to 300 lines of implementation code or less;
-
We lock the module’s interface signatures (contracts/) and full set of acceptance tests (tests/acceptance/) from Layer 3 as solid as diamonds;
-
When a business module repeatedly exhibits regression bugs across 3 consecutive fix work orders, or its cyclomatic complexity approaches the ceiling, stop patching immediately!
-
Simply keep the read-only interface and acceptance tests, completely delete the module’s internal business implementation source code in one command (
rm -rf src/features/xxx/impl.ts), and have the AI regenerate a clean implementation from scratch in 2 minutes against the read-only contract and red-light tests!
As long as the contracts and acceptance tests are locked, the business implementation code inside the module is a single-use consumable that can be thrown into the shredder and reprinted at any time. You never need to do archaeological maintenance on any piece of bad code ever again.
There is one frequently overlooked variable: the models themselves are rapidly improving. Having today’s model patch code written three months ago by a previous generation of model is like asking a new model to accommodate the limitations of an old one. But keeping the contracts and acceptance tests unchanged and rewriting the entire middle implementation allows every rewrite to directly leverage the latest generation of model’s capabilities. Given the current pace of model progress, keeping contracts unchanged and periodically rewriting the middle implementation is very likely the best solution: what the contracts capture is human understanding of the business — the implementation code is merely one generation of model’s translation of that understanding.
Conclusion: From “Bricklayer” to “System Legislator”
Looking back over the fifty-year history of software engineering, every generational leap in productivity — from assembly to high-level languages, from manual memory management to garbage collection (GC), from hand-operated physical machines to Kubernetes declarative container orchestration — has essentially been doing the same thing: pushing fragile details that once required humans to maintain through “self-discipline, memory, and careful caution” down into “hard physical constraints” enforced by compilers, runtimes, and infrastructure.
Today, facing the tsunami of code productivity brought by AI agents, the same playbook is unfolding:
-
If you still think like a “traditional bricklayer” — either hand-editing every line of code AI spits out, or letting AI run wild in a repo with no guardrails — then within two months, you will be drowning in a quagmire of architectural rot and review bankruptcy;
-
But if you choose to step back and complete the role transition to “System Legislator” — pouring all your engineering wisdom into designing vertically cohesive directory topologies, defining exhaustive algebraic types, welding shut immutable higher-order harnesses and state machines, writing AST gates with built-in fix prescriptions, and building a simulation test foundation with I/O counters.
Then every time AI does something stupid, it will no longer raise your blood pressure — it will instead motivate you to weld one more steel bar onto the iron cage of the five-layer pyramid. Ultimately, human engineers will completely leave behind the drudgery of brick-carrying and firefighting, and truly seize sovereignty over wielding infinite compute.
One final addition: the five-layer pyramid protects everything before code merge. No matter how tight the gates are, they cannot catch every problem — bugs will always slip past all tests and reach production. So after the merge, a more comprehensive observability stack of metrics, logging, and tracing — along with safety nets like canary releases, feature flags, and one-click rollbacks — is absolutely essential. Metrics tell you whether the system has gone wrong; logs and distributed traces tell you where the problem is; and rollbacks ensure you can restore production before you finish reading the code AI wrote. The faster AI writes code, the more errors there will only be. The speed of detecting problems and restoring service must keep up with the speed of writing code.
That concludes my recent thoughts on code governance in the AI era.
Similar Articles
@thinkszyg: The AI Coding Speed Paradox: Coding 48% Faster, Review 6x Slower. How to Rebuild the Review Process? SD Times Analyzes Data from 250,000 Developers: AI Boosts Coding Speed by 48-58%, But AI-Generated PRs Get Stuck in Review for 4-6x Longer…
The article points out that AI coding increases coding speed by 48-58%, but code review time increases by 4-6x, and security vulnerabilities also rise. It proposes a three-step plan to rebuild the review process: AI pre-review, focusing on architectural decisions, and using Microsoft's open-source ASSERT framework for behavioral verification.
Coding in the AI era: What if we're keeping humans in the wrong part of the loop?
作者探讨在AI编码时代,开发者应重新思考人类在工作流中的位置:与其让AI每一步都经过人工审核,不如让AI自主实现、人类专注于验证、测试与挑战假设,从而获得更大生产力提升。
@KengGuangLong: In the era of Vibe Coding, why has software engineering become more crucial? AI has reduced the cost of running code to nearly zero. Creating a feature or a prototype happens at an astonishing speed. However, the bottleneck has shifted: the real challenge now is whether it can be modified later. The biggest problem with vibe coding is that it...
In the era of Vibe Coding, AI makes code generation easy, but software engineering principles like code maintainability and design patterns become more important to address challenges in review, debugging, and refactoring.
@realchendahuang: I'm really curious about one question: Everyone's doing AI coding every day—how exactly do you avoid projects quickly d…
A developer asks how to prevent AI-assisted coding projects from quickly degrading into unmaintainable, low-quality code — a widely shared concern about code quality with AI tools.
@AYi_AInotes: Say a hot take: In the AI era, the most valuable skill is no longer writing code. Being able to explain code clearly will become increasingly important! Becoming increasingly important! @trq212, a senior engineer on the Anthropic Claude Code team, took less than two years to make his technical articles reach stable...
This article explores the importance of technical writing in the AI era, citing the case of Anthropic employee @trq212 who achieved millions of page views through his 'plant first, harvest later' writing methodology, emphasizing the value of sharing real experiences and maintaining a personal voice.