Engineers Design. Agents Implement.

šļø Engineers Design. Agents Implement.
Theme of this issue: AI writes the code. But who owns the decision? Three articles this week that all say the same thing from different angles: the craftsmanship isn't in the typing ā it's in the judgment about what NOT to build.
šÆ Hook
The scariest thing about AI-generated architecture isn't that it's wrong. It's that it's articulate.
A well-written wrong answer short-circuits the argument. Nobody pushes back on a proposal that already has diagrams. Nobody questions a refactor that comes with unit tests.
And at 3am when the system falls over ā Claude won't be paged. Your engineers will.
š„ Hot Take
š¬ My take: We outsourced the code. Now we're outsourcing the judgment. Those are different things. Code is reversible ā you can refactor. Architectural judgment is load-bearing. The moment you let an agent design your system without a human saying "no, not for our team, our constraints, our production reality" ā you've taken accountability off the table. And that's the one thing AI genuinely cannot hold.
š° Top Articles
1. Claude Is Not Your Architect. Stop Letting It Pretend.
TL;DR: Charlie Holland's argument is blunt: AI is pathologically agreeable. It can't say no ā and saying no is the most valuable thing a real architect does. AI-designed systems are technically sound for the median company. Your company isn't median. When it breaks at 3am, no one who made the architectural call will be paged.
My take: The detail that stuck ā "a senior reviewed it" has stopped meaning real pushback. The articulate AI proposal kills the debate before it starts. That's the accountability gap. It's not about code quality. It's about whose name is on the decision.
2. TypeScript Tips Everyone Should Know
TL;DR: 15 practical TypeScript patterns that go past the basics. The two that matter most: satisfies over as (validate without widening), and the hardest truth ā TypeScript ā runtime safety. as User after response.json() is a lie your compiler is happy to tell you.
My take: Most TS devs use 20% of the type system. The remaining 80% ā discriminated unions, never exhaustive checks, derived types from values ā is where bugs are actually prevented at design time. AI generates typed code that compiles. Whether it's safe at runtime boundaries is still your problem.
// The lie most devs write
const user = response.json() as User; // compiles. not safe.
// What you actually need at boundaries
import { z } from 'zod';
const UserSchema = z.object({ id: z.number(), name: z.string() });
const user = UserSchema.parse(await response.json()); // runtime-safe
// satisfies > as ā validates the shape, keeps the specific type
const config = {
port: 3000,
host: 'localhost'
} satisfies ServerConfig; // error if shape is wrong, literal types preserved
// exhaustive never check ā compiler catches missing cases on refactor
function assertNever(x: never): never {
throw new Error(`Unhandled case: ${x}`);
}
type Status = 'loading' | 'success' | 'error';
function handleStatus(s: Status) {
switch(s) {
case 'loading': return showSpinner();
case 'success': return showData();
case 'error': return showError();
default: return assertNever(s); // add a new Status ā compile error here
}
}
3. Clean Architecture on Frontend ā Alex Bespoyasov
TL;DR: Uncle Bob's Clean Architecture applied to a React/TypeScript cookie store with working code. The core rule: Domain layer depends on nothing. Use cases are "imperative shells" around pure domain functions. Ports & Adapters = switching Stripe to PayPal touches one file.
My take: The minimum viable version of this is two rules: (1) extract your domain logic into pure functions, (2) never let domain code import from UI or API layers. You don't need the full onion. You need the dependency direction to be clear. AI can generate the boilerplate ā but defining what is domain and what is adapter is still a human call.
// Domain layer ā pure, framework-free, testable in isolation
// src/domain/order.ts
export function createOrder(user: User, cart: Cart): Order {
return {
id: generateId(),
user,
items: cart.items,
total: cart.items.reduce((sum, item) => sum + item.price, 0),
date: new Date(),
};
}
// Application layer ā use case as "imperative shell"
// src/application/orderProducts.ts
async function orderProducts(user: User, cart: Cart): Promise<void> {
const order = createOrder(user, cart); // pure domain fn
const paid = await payment.tryPay(order.total); // adapter (port)
if (!paid) return notifier.notify('Failed'); // adapter (port)
await orderStorage.save(order); // adapter (port)
await cartStorage.clear(); // adapter (port)
}
// Adapter ā payment implementation, swappable
// src/adapters/stripePayment.ts
export const stripePayment: PaymentService = {
tryPay: async (amount) => {
const result = await stripe.charge({ amount });
return result.success;
}
};
// Switch to PayPal? Write paypalPayment.ts. Touch nothing else.
š ļø Tools & Releases
Hy3 / LLM pricing reality check ā Max Woolf investigated why Tencent's obscure Hy3 model is #1 on OpenRouter. The real story isn't Hy3 ā it's the cache economics hiding behind sticker prices. 98% of LLM API costs are input tokens. DeepSeek V4 Flash charges 2% for cache reads (industry standard: 10%) ā making its effective cost 5x lower than its listed price. Stated LLM pricing is now misleading. The real competition is on cache hit rates, not sticker prices.
ā Full breakdown by Max Woolf
š” Dev Tip of the Week
Put this in your CLAUDE.md (or Cursor rules). It's the one instruction that keeps AI from replacing architectural judgment:
# NOT-FOR-AI section
## Decisions that require a human
- Any change that adds a new layer or abstraction
- Choosing between two architectural patterns
- Deciding what belongs in domain vs adapter
- Anything that crosses a bounded context boundary
For the above: stop, describe the options, ask me to decide.
AI is great at implementing a decision. It's bad at knowing when a decision needs to be made at all. This forces it to surface the fork in the road instead of silently picking one.
š¤ Community Question
ā When AI generates your architecture ā and it breaks at 3am ā who do you call? Does your team actually know who owns the design decisions in AI-assisted projects, or is it diffuse?
š What I'm Learning / Building
Writing is an engineering problem. MIT researcher Rachel Yang reframed it this way: red marks on a draft aren't failure ā they're iteration. Same loop as code: design ā test ā fail ā revise.
Senior engineers communicate better not because they're naturally gifted writers. It's because they've shipped enough broken systems to know that writing is thinking made visible. If you can't write the architectural decision clearly, you haven't made it yet.