Addison Lynch

Automate the 90%. Hand the last 10% back to yourself.

·5 min·harness

Every automation has a cliff. The first 90% of a workflow is a week of work and runs unattended for months. The last 10% is the part with modals, multi-screen flows, dependency graphs between tickets, and every edge case you haven't met yet. It costs more than the first 90% did, and it never finishes, because the model, the vendor, and your own product keep moving underneath it.

the last 10%0%90%100%coverage of the workflowefforta week, then it runs for months
fig. 1 · the automation cliff. Effort against coverage. The curve does not flatten out at the end; it stands up.

The trap is that the last 10% looks like the same kind of work as the first 90%. It isn't. The first 90% removes toil. The last 10% is a product, and if you aren't in the business of selling automation, someone who is will ship it before you finish.

The QC agent that ate the harness

Here is how I learned this. By midsummer the harness was shipping several PRs a day, each one gated, reviewed, and merged by me. What it did not have was anyone checking, the next morning, that yesterday's merges actually worked. So I wanted a daily QC pass: take every PR merged in the last 24 hours, and try to break it.

Three kinds of change go out. Frontend changes to the BelowNew web app. Pipeline changes to how listings are collected, matched, and stored. And harness changes to the machine itself. I handed a batch of merged PRs to the agent and let it work out what a daily QC run should look like.

What came back was a lot of code.

For the UI it wrote Playwright scripts, one per feature, each asserting the specific DOM the feature happened to render that week. For the pipeline it wrote SQL scripts, one per invariant it could think of. It wanted a fixture library. It wanted a results schema. The skill file describing all of this ran to a couple of hundred lines before it had checked a single PR.

what the agent built first

  • Playwright scripts, one per feature ~40 files
  • SQL checks, one per invariant ~25 files
  • Fixture loader + results schema ~600 lines
  • Orchestration skill ~250 lines
surface area for drift: every file

what shipped

  • A QA persona: try to break it, show evidence 1 file
  • UI recipe: manual testing steps 1 file
  • Pipeline recipe: invariants + common changes 1 file
  • Permission to discover the rest at runtime 0 lines
surface area for drift: three prose files
fig. 2 · counts are approximate. The first column was never finished. The second has run every morning since.

Three things were wrong with the first column. I now owned a test suite I didn't write and couldn't read in one sitting. Every script was a new surface that would drift the moment the app changed, and the app changes daily. And none of it matched what I would actually do by hand, which was open a fresh session and say go try to break this feature. That usually worked. So why did the automated version need two hundred lines to do the same thing worse?

What the 90% looks like

Three prose files

We pulled everything back to prose. A persona file that makes the agent think like a tester: break everything, present evidence for every finding, remember that every feature has an inverse. A short UI recipe with the manual testing steps I'd give a human. A pipeline recipe with the data-integrity invariants that must never break, and a few starting recipes for the kinds of pipeline changes that ship most often, pulled from an actual analysis of the last two months of merges.

Two locks

Then two hard constraints, enforced with hooks rather than instructions. The agent gets no access to the code, because with code access a QC agent quietly turns into static analysis and stops using the product. It sees only what a user can see. And it gets a read-only connection to prod, because checking a pipeline change means looking at what actually landed in the table, not what the migration said would.

yesterday's mergesevery PR, last 24hQC agentpersona + 2 recipesthe live sitebrowser only, no repoprod databaseSELECT onlyfindingsevidence for every claimticket, or me0 / 5 · runs once, every morning, then exits
fig. 3 · the daily QC loop. Red edges are the two hard constraints. The agent files through the same roadmap skill I use, so ticket-filing rules live in one place.

That is the whole thing. Three prose files and two locks. It found real bugs in its first week: a sort order that silently reversed, a source filter that dropped a venue, a batch of listings whose condition tier had been mapped to the wrong bucket. Not one of those would have been caught by the Playwright scripts, because the scripts asserted the shape the agent had seen, and the bugs were in shapes it hadn't.

Don't let the substance of an automated process become more complicated than what you would do if you just prompted the agent yourself.

What the 10% looks like, and why you keep it

There is still a 10%. Some findings need a judgment call only I can make: is this a bug or a product decision? Some checks need a login the agent should never hold. Some flows span three screens and a modal and would take a day of scripting to make reliable, for a feature that changes weekly.

The handoff

The old instinct is to harden. Write the login helper. Script the modal. Add a retry. Each step is reasonable and none of them ends, because the surface keeps moving. What worked instead was to hand that slice back to myself on purpose, with the agent doing everything up to the handoff. It writes the manual steps. It puts them in the ticket, which is where I already am every morning. It attaches the evidence it did collect. Then it stops, and the fallback is the design rather than the failure.

This is advice for one person shipping a product. If the reliability of the automation is the thing you sell, the last 10% is your job, and this principle inverts. For everyone else, the cliff is real, and the way to stay off it is to notice when the work has stopped removing toil and started building a product you didn't mean to build.

Metadata

Browser
Current time
Words900
Last deploySep 03, 2026