How I use M3 for the boring 80% of coding

The “boring 80%” of coding is the part that isn’t fun, isn’t hard, but has to get done. Updating imports after a library upgrade. Adding type hints to a file. Renaming a function across the codebase. Writing the same test pattern for the 50th function in a module. M3 does this work. M3 does it well. M3 does it cheap.

Here’s the workflow.

The default

For any change that fits one of these patterns, I open M3 first:

  • Mechanical refactor (rename, move, split)
  • Type hint pass on a file
  • Test pattern repetition
  • Docstring pass on a module
  • Dependency upgrade (update the import, update the call site, update the type)
  • “Make the linter / type checker / formatter happy”
  • Convert a loop to a comprehension (or vice versa)
  • Add the obvious missing method to a class

These are the changes where the right answer follows from the inputs. The model just needs to produce the diff. The diff is mechanical. The diff doesn’t require understanding the system as a whole.

The prompt shape

The prompt for M3 work has a specific shape:

[Specific change]. [Constraints, if any]. [What to run after, if relevant]. [What NOT to do, if relevant].

Examples:

Add type hints to src/homelab/parser.py. Use the style already in src/homelab/utils.py for reference. Don’t add new dependencies. Run mypy after.

Rename parse_log_line to parse_log_entry everywhere it’s used. Don’t change behavior. Run the tests after.

Convert this loop to a list comprehension. The function should still return a list, not a generator. Run the tests after.

The prompt is short. The prompt is specific. The prompt includes what “done” looks like (the type checker, the tests, the formatter). M3 uses the “done” criteria to verify its own work.

The review

The review for M3 work is fast. I read the diff. I check that:

  • The right files changed
  • The right files didn’t change
  • The new code matches the conventions in the surrounding code
  • The “done” criteria (tests, type checker, linter) actually pass

The review takes 30-90 seconds for most M3 changes. The model produces tight diffs. The diffs match the surrounding code. The “done” criteria pass on the first try about 80% of the time.

When the review catches something, the feedback is specific:

parse_log_line is still used in tests/test_parser.py:42. You renamed it in 6 of 7 places. Find the 7th.

M3 fixes it. The fix is mechanical. The model handles it.

The escalation

When M3 fails, the failure mode is one of:

  • The model goes off-script (does something I didn’t ask for)
  • The model hallucinates an API (calls a function that doesn’t exist)
  • The model produces a diff that’s correct but the review catches a real problem

For the first two, I escalate to Claude. The escalation is rare. The escalation is worth the cost because Claude will produce the right diff on the first try, and the right diff is cheaper than two wrong diffs from M3.

For the third (M3 produced something that needs more thinking), I take over. I read the problem. I write the fix. M3 was the wrong tool for the task. The next time, I’ll know earlier.

The cost

For a week of M3 work, I used about $4 of model time. The same week of work with Claude would have been about $30. The same week of work with GPT-5 would have been about $25. The cost saving is real.

The cost saving comes from two things:

  • M3 is cheaper per token
  • M3 is good enough that I don’t escalate often

If M3 escalated 50% of the time, the cost saving would disappear. M3 escalates about 10% of the time. The cost saving is real.

The thing M3 is not for

M3 is not for:

  • Bug hunts (use Claude)
  • Architecture decisions (use me)
  • Anything that needs deep context (use Claude)
  • Anything that requires the model to push back on me (use Claude)
  • Anything where I’m not sure what the right answer is (use me)

The boring 80% of coding is the right answer following from the inputs. For that, M3 is the right tool. For the 20% where the right answer doesn’t follow from the inputs, M3 is the wrong tool.

The 80/20 split is the workflow. M3 for the 80%. Claude for the 15%. Me for the 5%. The cost and the time follow from the split.


← back to all posts