跪拜 Guibai
← Back to the summary

AI changed your code but you can't tell what it did: Architecture drift is the real cost

A very typical scenario: I had an Agent do what seemed like a small task, adding audit logging for order cancellation.

It changed more than a dozen files, and tests passed. I opened the diff, stared at it for twenty minutes, and in the end could only confirm one thing: It runs. But what it did to the system's structure, I couldn't say.

This isn't a one-off failure; it's an increasingly common state in AI programming:

Code diffs keep getting longer, architecture changes keep getting more hidden.

When a human changed code before, a review could reconstruct intent from file names and call relationships. Now an Agent changes a dozen files at once; each individual change looks reasonable, but taken together they might amount to a structural migration. What you see is a pile of line-level changes, not "the system went from A to B."

That's what I call architecture drift.

1. Code diffs don't show structure

A code diff answers "which lines changed." But what a person actually wants to know is:

Line-level diffs are hard-pressed to answer these.

Take a small example. To let order cancellation write audit logs, an Agent might do three things:

  1. Directly import the audit module in the orders module;
  2. Place the audit entity under the orders module;
  3. Conveniently stuff the "send audit event" logic into the order service.

Every line runs, and tests might pass. But structurally, the orders module now has a direct dependency on the audit module, the audit entity is in the wrong place, and the order service's responsibility has grown.

The next time someone wants to reuse audit capability in another module, they find it's welded to orders; the time after that, someone wants to split a module and finds dependencies already tangled.

The AI isn't deliberately writing messily. It's making the most locally rational decision: whatever exists in the current file, use what's nearby. The problem is it has no stable global structure to reference, so each local optimum adds up to overall drift.

2. Architecture drift has three common forms

1. Dependency drift

orders was supposed to depend only on domain, but to save effort it directly depends on payment. The code runs, but the layering is pierced.

2. Boundary drift

One utility function is copied into three modules; an entity that should be internal is referenced across modules; a new module is never formally registered and exists only inside some directory.

3. Semantic drift

Module names haven't changed, but responsibilities have. orders starts handling notifications, notifications starts assembling order queries. The name is still the name, but the system is no longer that system.

These three kinds of drift share one trait: tests don't necessarily fail, and code review may not see it either.

3. Why prompts can't contain drift

We usually write in prompts:

Don't touch the payment module. Don't introduce new dependencies. Preserve the existing architecture.

These aren't useless, but they're soft constraints.

Once an Agent's context gets long, early constraints get diluted; when it hits a "by the way" call, it might decide changing is more reasonable; more often, it simply doesn't consider it "changing architecture" — it's just making the code pass.

Prompts can express intent, but they can't form checkable structural facts.

4. Jin's approach: turning structure into checkable facts

Jin has the project maintain a small two-layer architecture:

When an Agent wants to change structure, it doesn't directly edit the formal architecture; instead it creates a proposal and edits a target snapshot. Validation checks references in the target architecture, public entities, and layering constraints; after application, drift checks compare against real code:

Once validation passes, a human approves, and the target is written into the formal arch/.

This doesn't slow down the Agent; it makes "structural change" explicit instead of implicit:

A person doesn't need to guess structure from a dozen-file diff; they first check whether structure changed.

Jin architecture diagram

5. Drift checks aren't a silver bullet

To be clear: Jin's drift check is declarative, not a full compiler.

It can find:

It cannot prove:

So it's not an "architecture correctness prover" or a replacement for code review. It solves a narrower but annoying problem: structural changes are invisible.

6. What I actually want is not a "faster AI"

I don't need the Agent to be faster. I need it, when changing structure, to leave something I can understand:

That's also where I started with Jin. It's not about making AI write less code; it's about making sure that after it writes, a human can still explain what happened to the system.

Project address:

https://github.com/ZYF93/opencode-jin

v2.0.32-jin.1 downloads (macOS / Windows / Linux):

https://github.com/ZYF93/opencode-jin/releases/tag/v2.0.32-jin.1

Full Chinese guide:

https://github.com/ZYF93/opencode-jin/blob/dev/JIN.zh.md

Jin is a community fork of OpenCode, not an official OpenCode product. The project is still early; feedback is welcome.

Comments

Top 1 from juejin.cn, machine-translated. The original thread is authoritative.

lollollollol

Thanks for sharing