productize.blog
AI · Skills Map · Part 2

You didn't skip the decision.
You made it without looking.

Andrew Ng says software fundamentals still matter because you need them to steer a coding agent. The harder half of his sentence is about knowing which tradeoffs exist at all. A missing answer you can see. A missing question is invisible, and the code compiles either way.

Yim· written with Dobby (AI Oracle)/Aug 30, 2026

The code ran. The tests were green. You shipped it, and for three weeks nothing happened. Then the bill for one service climbs with no matching climb in users. Or a page that loaded instantly takes four seconds, and only for your oldest customers. Or two people open the same screen at the same moment and see different numbers.

Nobody wrote a bug. There is no stack trace, no failing test, no line in the diff that looks wrong. Go back and read the change that caused it and you find something small, tidy and entirely reasonable. That is the shape of the problem this piece is about, and it has one cause: a decision was made in your repository by something that was not you, and nothing about it looked like a decision at the time.

Productize reads the vibe coding vs agentic coding split as a question of ownership rather than of skill. This is Part 2 of a reading of Andrew Ng's AI engineering skills map: Part 1 covered the skills map and the AI-specific skills on it. This one covers the software half, where the silent decisions live.

Part 1The clause the whole essay rests on

Andrew Ng's essay on software fundamentals opens with a question and answers it in one sentence. That sentence does two jobs, and most people read only the first.

Even when you use a coding agent to write all your code, understanding software fundamentals is important for steering your agent to make the tradeoffs you want
or to even know what tradeoffs exist to be made.

The first half is the familiar argument: know enough to point the agent in the right direction. The second half is a stranger claim. The dangerous case is not being wrong about a tradeoff. It is not knowing one was there.

A missing answer is recoverable, because you can see the gap. A missing question is not, because it has already been answered. If you do not know how to configure a cache, you notice, look it up, decide. If you do not know a cache has to be invalidated, nothing prompts you. The agent picked a value, the tests pass, the page is fast, and the wrongness is scheduled for three weeks out.

Andrew Ng names the mechanism plainly: the novice who vibe codes gets working simple applications and, with them, bad tradeoffs, because "the developer didn't know such tradeoffs even existed and therefore did not steer the agent to make the right decisions for their application context". He gives the vocabulary once and never returns to it: "latency, availability, consistency, reliability, maintainability, simplicity, and/or cost". Those seven are what every decision below trades against each other.

Before going further, it is worth seeing the whole map. Ng splits software fundamentals into five pillars, in this order: building full-stack applications · managing data · designing system architectures · making systems secure and reliable · and scaling and operating in production. The rest of this essay walks them in that order. Part 2 stands on the first, Part 3 on the second, where we stay longest, and Part 4 takes the last three together, because they fail by the same mechanism. The other branch of the same map, the six sub-skills of building and deploying AI applications, is Part 4 of the first essay.

AI Engineering Building and deploying AI applications Software engineering fundamentals Using coding agents Shaping the build Building full-stackapplications Managing data Designing systemarchitectures Making systems secureand reliable Scaling and operatingin production
The same map as Part 1, redrawn from the skills Andrew Ng lists. The rust box is the software half, which this essay walks one pillar at a time.

Part 2Does agentic coding enable you, or conscript you?

Pillar 1 · Building full-stack applications

It conscripts you. Ng frames the widening of your role as an opportunity, and that framing is too gentle for what happens in a repository.

His version: "Agentic coding enables many developers who previously played more specialized roles (like front-end developer or mobile developer) to play a broader, full-stack role." As a description of capability, true and cheering.

Ng does not say the next part; we do. Enables implies you could decline. You cannot. The cache-invalidation decision and the state-placement decision land in your repository whether or not you know they exist, because the agent has to write something and it will not stop to ask. There is no version of using a coding agent where you decline the decision. There is only a version where you make it without looking. Which changes the advice. Not you may now expand your role, but the expansion already happened, so the only question is whether you are watching.

An agent's lean when nobody is watching is predictable: toward whatever is most written about. The tutorial answer, the single-user answer, the one-process answer. Silence from you is not deferral. It is a decision made by whatever the model has read most of.

Here is what that looks like. You ask for a faster dashboard. The agent adds a five-minute cache in front of the summary query, held in the app's own memory. On your laptop it is correct: one copy of the app, one user. In production there are four copies behind a load balancer, software that spreads incoming requests across whichever copies are running. A user edits a record, the write lands on copy two, and the next request routes back to copy one, where the edit has not happened. So they do it again. Now there are two records. Nothing errored.

The tell is cruel: severity scales with how many copies you run, so it worsens right after you scale up, sending everyone into the scaling change instead of the caching one. The instruction that would have prevented it is not be careful with caching. It is: name the write that invalidates this cache, implement it in the same change, and never keep shared state in one process's memory.

Part 3Why is data the one pillar that fails in silence?

Pillar 2 · Managing data

Because its failure has no output. Every other part of the stack eventually produces something loud: a timeout, an error page, a bill. A data architecture that is missing something produces a confident, plausible answer, and nothing in the system looks different from success.

Ng treats data differently from the other pillars, saying it "deserves special attention" because it is "a foundation that software is built on top of, that is relatively hard to change (even if agents help with migrations)", then makes the essay's one AI-era claim: "Your AI systems will get their own input context from your data source, so if data architecture is chosen poorly, the AI doesn't know what it doesn't know."

This is the same decision the first essay called grounding with data, seen from the other side. That side asks whether to store it as a vector index (searched by closeness of meaning), a knowledge graph (which records what relates to what) or a semantic layer (a mapping that lets a query use business words like customer instead of raw table names) over tables you already have. This side asks how you would ever find out you chose wrong. The mechanism is stronger than the usual complaint that bad data gives bad answers. A model's output is a function of its context, and its context is assembled by code running against your data layer. So the outer edge of what the system can know is the edge of what that layer can return, and nothing inside the model can see that edge from the inside. A person who does not know something can notice the gap. A model handed a truncated context does not experience a truncation. It experiences a complete context.

The sharpest form of this is one sentence long. An empty result set is the same bytes whether the answer is genuinely none, or the question was never answerable from that schema. No query language can express the difference, because the distinction lives in the collection history, meaning how and why those rows came to be gathered at all, and that history is not in the database.

This is the exact opposite of the failure we wrote about in why your AI agent lies to you. There the model invents something that was not in front of it. Here it invents nothing: it answers correctly, over a smaller world, with no signal that the world was smaller. Which is why a better model does not fix it. A better model given the same context reaches the same answer with more polish. It is a data problem that presents as a model problem, so teams misdiagnose it and spend months tuning prompts at it.

Four ways a fact becomes invisible, worth naming on sight:

The everyday version of all four is NULL. In real schemas it stands in for at least five meanings: not applicable, unknown, not yet collected, collected and genuinely empty, and lost in a migration. A model reading a NULL cannot tell them apart. Mostly, neither can we. Which makes one review question unusually productive on a generated schema: what does NULL mean in this column, and is it more than one thing?

Ng states the problem and prescribes nothing, leaving a warning about an invisible failure with no instrument attached. The best instrument we know sits at the boundary where an agent reads. A retrieval tool asked to filter on a dimension the source does not have should return an explicit this field is not available here, never an empty list. That converts a silent absence into a token in the context, which the model can read, report and route around.

Then prove that instrument can fire. Ask something whose answer you know lies outside the retained window, and assert that the system reports it cannot see that far. A retrieval layer that has never once reported a limit has not shown it can detect one.

Part 4The last three pillars fail the same way

Pillars 3-5 · Architecture · Security and reliability · Scaling and operating

Pillar 3, designing system architectures. This is where the essay makes its quietest good point: "the right architecture is a moving target, depending on the phase of the project". The prototype shape is not the first-production shape, and "that too may change as the application scales". Cheap generation is an argument for committing later, not bigger.

Ng stops there. The part we would add is where irreversibility actually sits. One-way doors are not spread evenly through a system. They cluster at its edges. A published URL, an API shape a second client adopted, an ID a user can see, the tenant key that separates one customer's rows from another's once a migration has touched it, where the bytes physically live, what you promised to delete. Internals stay reversible far longer than people assume, and interfaces become irreversible far sooner. The rule that falls out: spend deliberation at the edges, speed in the middle.

Prototypes are the trap inside that rule, because they feel disposable. Their code is. Their published URLs and the real user data they ingested are not: the moment a prototype touches personal data it picks up obligations that outlive every line that created them.

Underneath it is an asymmetry agentic coding created and did not advertise. Generation got dramatically cheaper. Migration got a little cheaper, since an agent rewrites every place in the code that calls the old shape but cannot negotiate a contract change with consumers you do not control. Operating cost did not move at all: it is a function of surface area, meaning how much system exists to be run, watched and secured, and surface area does not care how the code was authored. So cheap generation did not make good architecture cheaper. It made wrong architecture cheaper to acquire and left it exactly as expensive to own. Nobody hand-built seven services for a prototype, because nobody had the weekend. The friction of typing was acting as a limiter on ambition, and removing the friction removed the limiter, not the cost.

Pillar 4, making systems secure and reliable. Ng asks two things here. First a testing strategy: what mix of unit and integration tests, which frameworks, what level of coverage. Second, designing around failure up front, from handling an API that hits a rate limit to graceful degradation, keeping a reduced version running instead of failing outright, to "minimize the blast radius of failures", which is how far a failure spreads before something stops it. He also notes that security work is moving earlier in the lifecycle under "shift left", to the point that "many developers are now also partly security engineers". The failure we keep meeting in this pillar is not too few tests but tests that cannot go red, and checks that report green for the wrong reason. In production, an alert that has never fired and an alert that is broken look identical from outside, because both produce silence.

Pillar 5, scaling and operating in production. Ng's list here is long and unglamorous: configuring the deployment environment, choosing a release strategy, deployment automation, then observability (being able to tell what the system is doing from outside it), alerts, incident management, and finally scaling through sharding (splitting one database across several machines), indexing (pre-building lookups so a query need not scan every row) and replication (keeping copies of the data on more than one machine). The line that ties this pillar back to the whole essay is the instruction to "understand the real load", because real load is the only thing that can tell you whether the in-memory cache across four replicas from Part 2 is a problem yet. The agent gave you code that deploys. It has no way to know what your load looks like, because it has never seen it.

All three of these fail the way the first two did: a decision was made and nobody was looking. The question that works on every pillar is the same one: what would have to be true for this to tell me something?

Part 5What can you ask of a diff tomorrow?

Ask questions you can answer by reading, without running anything. Every one is recognition rather than implementation, which makes the skill acquirable on work you already do. If you cannot answer one from the code in front of you, that is the finding, and the agent's default stands.

None of those requires you to write the implementation yourself. That is the point: these fundamentals are learnable at review time, not only in a curriculum.

Ng closes by saying developers who deeply understand how software works "vastly outperform those who vibe code without understanding". He attributes it to an internal study and publishes no figures, so take it as a considered position rather than a measured result. Our version is narrower and harder to argue with: the agent makes the decision either way, and the only variable is whether anyone looked.

The other half of the map is the AI-specific skills sitting on top of these fundamentals: Part 1, Andrew Ng's AI engineering skills map.

Box 3 of the map is using coding agents, and the question the map never asks is who reviews the reviewer. Read it in Part 3, Using Coding Agents.

Box 4 of the map is shaping the build, and the question the map never answers is where the line Andrew Ng tells you to respect actually sits. Read it in Part 4, the line you must measure.

Finished the app but not sure where to host it? We compared the options by job in Hostinger, Vercel, Cloudflare: pick by job, not intro price

Source

§

Follow along

Get new posts and free resources first

Leave your email. New posts and the occasional free resource land in your inbox. No spam.

Email only, for updates.

Comments

Join the conversation

Share a thought.

Name is shown publicly. Email stays private and is never shown.

Loading comments…