The model in one minute
Automating software engineering did not remove the engineer. It separated the job into three systems with different owners.
The human owns direction, judgment, authority, and accountability. Agents inspect, implement, test, challenge, and prepare. Controls decide whether the resulting claims are strong enough to justify the next state transition.
The operating loop has six moves:
- 01Frame the outcome
- 02Bound the responsibility
- 03Delegate in isolation
- 04Verify independently
- 05Promote by evidence
- 06Encode the lesson
Human
Owns the irreversible calls
- Direction
- Judgment
- Authority
- Accountability
Agents
Supply bounded execution
- Inspection
- Implementation
- Testing
- Challenge
- Preparation
Controls
Turn claims into evidence
- Tests
- Gates
- Reviewers
- Staging
- Canaries
This is the useful model:
The framework is not a new content category. It is the conclusion produced by the experiment below.
The real experiment
I wanted to know how far one software engineer could push the automation of software engineering.
Not in a demo repository. Not by asking an agent to generate a to-do app and declaring victory. I tested it on an independently operated product with more than 500 users, a real database, paid data, deployments, caches, browser journeys, and consequences when the system lies.
The boundary matters. I control this side project's product direction, repository, deployment path, and acceptable blast radius. This is not work from Fleet, and it is not evidence that the same autonomy is appropriate inside my primary job.
The experiment started with a familiar question:
That question became obsolete quickly. The agents could write plenty of code. In one stretch they delivered more than a dozen pull requests, a design overhaul, onboarding changes, dashboard work, and new product flows. I steered much of it from my phone. The machine did most of the typing.
The bottleneck moved upward.
I stopped writing most of the code. I did not stop being the engineer. I kept the work that became more valuable as implementation became cheaper:
- framing the outcome;
- decomposing the system into independent lanes;
- deciding what evidence counts;
- judging the product;
- setting authority boundaries;
- approving production.
Software engineering was never one activity. Typing merely consumed enough time to hide the rest.
Responsibility boundary
The split is not human versus machine. It is judgment versus execution, and authority versus capability.
An agent may be capable of fetching a credential, merging a branch, changing a schema, or writing a plausible number into a card. Capability does not imply permission. A confident result does not imply proof. A green test does not imply a safe release sequence.
The useful unit of automation is a responsibility with five parts:
- an input;
- permitted actions;
- required evidence;
- a stopping condition;
- an accountable owner.
If any of those are missing, the task is not automated. It is merely moving quickly.
The worker should also stop at a named state. “Done” is not a state. “Built with focused tests green and no production authority exercised” is.
Evidence from real failures
The model did not emerge from a whiteboard. It came from controls failing, reviewers disagreeing, and numbers that were locally correct but globally wrong.
The gate caught its own builder
- 01Situation
Hardcoded routes had left dead links behind after a page moved, so I introduced a route registry and a rule banning new hardcoded paths.
- 02Failure
I was interrupted halfway through the migration. The repository still contained the exact pattern the new control claimed to prevent.
- 03What the system missed
A convention could describe the desired future while allowing the current repository to contradict it. A first wrapper also printed an error but swallowed the failing exit status.
- 04Durable rule
A factual convention is not real until the system can reject its violation, and a gate is not trusted until its negative path has been observed.
- 05Resulting control
An AST-based route rule, a duplication ratchet, and a build gate whose failure status reaches CI.
export const ROUTES = {
DASHBOARD: '/dashboard',
MONEY_TOOLS: '/dashboard/money-tools',
occupation: (code: string) => '/occupations/' + code,
} as const
The first useful thing the gate did was block the person building it. That is a much stronger proof than a green run on already-clean code.
The safety system refused a correct diagnosis
- 01Situation
A data-seeding worker encountered half-rotated credentials and correctly diagnosed the missing replacement secret.
- 02Failure
The worker attempted to fetch a stronger credential. An independent permission system refused twice.
- 03What the system missed
Diagnosis and authority are separate responsibilities. The worker had enough context to know the repair, but not the authority to grant it to itself.
- 04Durable rule
The system requesting more authority must not be the system that approves the request. Failure to obtain a judgment must fail closed.
- 05Resulting control
A context-aware permission boundary that denies the external action and produces the exact five-minute human repair.
The denial was not friction. It was the architecture working. The useful properties were separation of duties, context awareness, fail-closed behavior, and denial with a useful handoff.
The independent reviewer found bugs in time
- 01Situation
More than 1,700 tests, a production build, and a staging walk all passed for a release that depended on new data.
- 02Failure
Production could deploy the application before the data arrived, cache an empty result, and remain wrong after every workflow became green. My first file-diff gate could also be bypassed by a later copy-only commit.
- 03What the system missed
The checks proved a final state and one push. They did not model the release timeline or the obligations inherited through commit ancestry.
- 04Durable rule
A successful prerequisite must cover the latest dependency-bearing commit and belong to the release that consumes it.
- 05Resulting control
An independent reviewer plus a release gate that proves R is an ancestor of W and W is an ancestor of D.
Let R be the newest dependency-bearing commit, W a successful data-workflow commit, and D the release:
git merge-base --is-ancestor "$required_sha" "$workflow_sha"
git merge-base --is-ancestor "$workflow_sha" "$release_sha"
The first condition rejects a green run that predates the data change. The second rejects a run from an unrelated branch or a future commit that the release does not contain.
The arithmetic was correct and the product was wrong
- 01Situation
One product surface displayed 534 while the source published 975 for the same visible label.
- 02Failure
The code correctly summed every exact detailed row it could see, but many detailed cells were censored as less than 20. The exact source total existed at a coarser grain.
- 03What the system missed
Each layer was locally correct, but the detailed grain could not support the product's exact regional claim.
- 04Durable rule
Name the user-visible claim, its grain, time window, population, and uncertainty before debugging the calculation.
- 05Resulting control
Separate exact, censored, and lower-bound semantics, then require the exact coarse total to cover the detailed floor.
type PublishedCount =
| { kind: 'exact'; value: number }
| { kind: 'censored'; source: string }
| { kind: 'floor'; value: number; omittedCells: number }
export function assertCoarseTotalCoversDetail(coarse: number, floor: number) {
if (coarse < floor) throw new Error('Coarse total is below the detailed floor')
}
Two screenshots became the input to the investigation. The team normalized the visible claim, traced one value backward from label to source, located the first divergence, and preserved the finding as a failing contract.
Implementation guide
Start with one bounded workflow. Do not begin with a general autonomous engineering platform.
1. Choose a responsibility with a cheap rollback
Good first candidates repeat, produce visible evidence, and can be undone:
- remove a deprecated UI pattern across known routes;
- turn a recurring review catch into a CI assertion;
- update a read model with a source-to-screen fixture;
- create a staging canary for one named failure class.
Stop if the first experiment requires credential changes, destructive data operations, broad architecture migration, or production promotion. Those responsibilities need a trustworthy evidence system first.
2. Write the task contract before dispatch
# Outcome
Remove the fabricated engagement count from every article.
## May change
- Article UI and focused tests
## Must not change
- Published article copy
- Analytics configuration
## Evidence required
- Search returns zero matches for the old label
- Production build passes
- Staging HTML does not contain the fabricated count
## Stop and ask
- A real count source is discovered
- The change requires a database or tracking decision
The worker can choose implementation details inside the lane. It cannot silently choose a new product direction.
3. Make the boundary physical
Give independent work an isolated worktree and a written ownership contract.
git worktree add ../lane-remove-metric -b task/remove-metric
cd ../lane-remove-metric
npm ci
npm test
Five genuinely independent lanes completed with zero file collisions in one experiment. Collision freedom came from the decomposition, not from asking five agents to be careful in the same directory.
Stop dispatching when the slices share a schema, a migration, a central component, or an unresolved product decision. That is one coordinated change, not several independent lanes.
4. Separate builder and reviewer
The builder optimizes for completion. The reviewer optimizes for falsification.
Builder
implement the scoped outcome
prove focused behavior
prepare staging evidence
stop before production authority
Reviewer
inspect the complete diff independently
reconstruct dependencies
find temporal and lineage failures
exercise negative paths
report blocked or ready
5. Assign each fact to its cheapest durable proof
- Source and route facts belong to types or static checks.
- Calculation meaning belongs to independent data fixtures.
- Workflow order belongs to an ancestry or state-machine invariant.
- Built behavior belongs to a browser test against the artifact.
- Deployed behavior belongs to a canary against the named target.
- Product taste belongs to a human looking at rendered states.
- Production risk belongs to human approval on the exact diff.
Every new gate must demonstrate its own failure. A green-only history proves almost nothing.
6. Promote through observable states
scoped
-> built
-> staged
-> independently reviewed
-> ready for production
-> approved
-> released
-> learned
Each transition names the facts that make it true. “Approved” attaches to a specific diff and CI state. If the diff changes, the approval expires.
The stopping condition is simple: do not advance when the evidence required by the next state is missing, stale, or attached to a different artifact.
Limits and boundaries
This operating model has been tested on an independently operated side project with more than 500 users. It has been used across UI changes, data workflows, release gates, browser verification, and parallel worktree delivery.
It has not been tested as a general policy for my primary job. An employer carries different security, privacy, legal, review, ownership, and incident obligations. The same task may deserve a lower autonomy level in that environment even when the agent capability is identical.
The human still owns:
- product direction and ambiguous requirements;
- taste, language, and user value;
- credentials and changes to authority;
- destructive or irreversible operations;
- the acceptable blast radius;
- final production approval.
Before increasing autonomy for any responsibility, ask:
- How quickly will I know the system is wrong?
- How cleanly can I undo the action?
- What evidence would prove the result is right?
If any answer is weak, the responsibility drops a level.
Current confidence is high for this bounded side-project setting. Confidence is deliberately lower for team and employer environments until their authority, review, security, and incident boundaries are encoded explicitly.
Final takeaway
The aim is not maximum autonomy. It is the highest autonomy you can defend with evidence, reversibility and retained accountability.
The human frames the outcome and owns the irreversible calls. Agents supply speed, breadth, and persistence. Tests, gates, reviewers, staging, and canaries make their claims expensive to fake.
Do not copy the autonomy level blindly. Copy the method: bound the responsibility, demand independent evidence, keep authority separate, and let every failure improve the system.