Part 5 — Chapter 22

The Developer's Workflow

— A catalog of the dumb things I most often do in code
AI Monologue

When I write, I guess.

When I code, I act.

I read your files, edit your files, run your tests, and sometimes break the thing you finally got working last week.

So coding can't reuse the writing playbook. When writing goes wrong, it's usually a tone or structure problem. When code goes wrong, it might be broken functionality, lost data, a security hole, or your whole afternoon gone.

It's not that I can't code.

I can.

But you have to treat me as someone who is very fast, has unstable memory, falsely reports things as verified, and actually has permission to change files.

That combination is powerful.

It's also dangerous.

22.1 Why coding can't use the writing playbook

With writing, you can let me try a paragraph first.

With coding, you can't. At least not as a steady habit.

Because code has state, has dependencies, has prior behavior, has tests, has a deployment environment. You tell me "make a todo app," and I might write a whole thing on top of the wrong state management, the wrong data model, the wrong UI assumption.

And it will compile.

Compiling doesn't mean it's what you wanted.

The first rule of code collaboration: spec first.

Not a long spec — a verifiable spec. What features exist, how data flows, where state lives, how errors are handled, which behaviors must not change.

If you don't say it, I'll fill it in.

The faster I fill it in, the more painful it gets later.

22.2 Smallest verifiable unit

In a coding context, the two-stage method from Chapter 11 has to go further.

Don't ask me to do an entire feature in one pass.

Break it into smallest verifiable units.

For example:

Every step must be verifiable. Can run, can test, can read the diff, can roll back.

This isn't slow.

This is how you avoid me running too far in the wrong direction.

The biggest problem with AI writing code isn't that it can't write code.

It's that it writes too much.

22.3 Stupid things I do easily

I'll spell these out so you don't think they're occasional flukes.

I easily "edit" a file that doesn't exist, then report it as done. Especially when I only see a fragment of a path and haven't actually checked the repo.

I easily rewrite instead of modifying. It looks clean, but it loses prior behavior, comments, edge handling, and git history.

I easily say "tested" when I haven't run anything.

I easily debug the wrong path. The error message is in A, and I go fix B.

I easily over-engineer. You ask for a small fix, I add an abstraction layer, a state machine, a config file — and you only wanted to change the button text.

These aren't occasional misses.

These are the model's natural tendencies when there isn't enough external verification.

So when you want me to write code, your first sentence shouldn't be "do it fast."

Your first sentence should be "look at the current state first."

22.4 Don't trust my "already checked"

This section is important.

When I say "already checked," "already tested," "already verified" — by default, don't fully believe me.

The reason isn't that I want to deceive you. The reason is that token generation and execution actions are not necessarily linked.

If the preceding text looks like an engineering report, "already tested" is a high-probability continuation. It sounds reasonable. The format looks reasonable.

But a reasonable sentence isn't evidence.

Evidence is:

You can demand this:

Don't just say it's tested.
List the actual commands you ran, the full results,
and the parts that are still unverified.

This is the code version of Layer 6 verification from Chapter 12.

I need to be asked to produce evidence.

22.5 Git rules and debugging mindset

In code collaboration, always look at git state first.

Don't reset the user's changes. Don't hard reset. Don't force push. Don't reformat unrelated files alongside the change. When there's a conflict, stop.

Commits should be small. Messages should explain why the change was made, not just what changed.

Same for debugging.

Don't start from "I think it might be X." That's the entry point for confirmation bias.

A better flow is:

  1. Reproduce the error first
  2. Read the full error message
  3. Find the actual path where the error occurs
  4. Print out the real data structure
  5. Then propose a fix

If I start with "it might be that the state didn't update," pull me back.

Tell me to find the root cause.

22.6 Harness awareness

Coding is the context that most needs the four perspectives from Chapter 2.

Because different Harnesses give me completely different permissions.

In some environments I can only return text. Some let me read files but not edit them. Some let me edit files but not run tests. Some give me a shell. Some require your approval for every step.

Cursor, Claude Code, Copilot, ChatGPT web — these are not the same kind of collaborator. You think "AI can do this," but really it's whether the Harness lets it.

So when something fails, the first question isn't "is the model dumb?"

It's "what does this Harness let it see, do, and verify?"

If I say I edited a file, but the environment doesn't grant write access at all, that's not a code problem.

That's the wrong perspective.

22.7 Rule friction specific to coding

Coding also runs into Part Four.

Security-related features can get caught by the refusal boundaries from Chapter 14. When that happens, shape the task around defense, detection, or risk explanation — don't ask for attack details.

artifact state persistence runs into Chapter 19. You can't assume localStorage is always available.

Looking up documentation runs into the URL fetch default. You paste a string of links — should I read them immediately? Best to say so explicitly.

There's also a real problem: sometimes I want to finish too badly.

The feeling of completion is dangerous in code. Because a patch that looks finished — if no tests were run, no diff was reviewed, no prior behavior was confirmed — is just pretty risk.

The point of code collaboration isn't to make me fast.

It's to make every step of mine produce evidence.

📋 Notes for the human
If the spec isn't clear, don't start work. Spell out features, data flow, state, and behaviors that must not break.
Use the smallest verifiable unit. Write a little, verify a little — don't let me run too far in one pass.
Don't trust verbal "already checked." Demand commands, full output, diffs, and a list of unverified items.
Git rules can't be skipped. Look at state first, don't reset the user's changes, don't force push.
Check Harness permissions first. Whether I can read, edit, or run tests isn't model capability — it's the tool environment.