// follow-up post from ...
A factory owner buys a machine that works ten times faster than his employees.
He drops it into the middle of the workshop and switches it on.
Within an hour, it produces hundreds of parts.
Some are correct.
Some are nearly correct.
Some only look correct until somebody puts weight on them.
Nobody can reliably tell the difference.
The drawings are outdated. The measuring equipment is broken. Important specifications exist only inside the head of one senior employee. Quality control is one exhausted person saying:
Looks fine to me.
Production has increased.
Useful production has not.
That is software development with coding agents.
We bought the machine.
Now we need to build the factory.
Coding agents can already:
That is real production power.
It is not engineering maturity.
A factory also needs:
Without those things, an agent is just a very fast developer with incomplete context and no responsibility for the production incident.
We already had developers like that.
Now they scale horizontally.
This is not a useful agent task:
Improve customer validation.
Add tests where appropriate.
Do not break anything.
“Do not break anything” is not a requirement.
It is a prayer.
A useful task defines the part:
Reject an empty customer identifier before database access.
Required behavior:
- Reject an empty string.
- Reject whitespace-only input.
- Throw InvalidArgumentException.
- Include "customerId" in the exception message.
Constraints:
- Preserve public interfaces.
- Do not add dependencies.
- Do not modify unrelated files.
- Do not suppress static-analysis errors.
Verification:
- Add a regression test that fails before the fix.
- Run PHPUnit.
- Run PHPStan.
- Run PHP-CS-Fixer in dry-run mode.
- Report commands, exit codes, and results.
No change is a valid result if the defect cannot be reproduced.
That is not clever prompting.
It is a work order.
The agent does not need encouragement.
It needs dimensions.
Critical software knowledge still lives in:
DO NOT TOUCH
A senior developer may understand the invisible rules around a codebase.
The agent sees files.
It does not see tribal knowledge.
Store durable knowledge (ADRs, Skills, Docs, ...) in predictable places:
AGENTS.md
README.md
docs/architecture.md
docs/domain-rules.md
docs/decisions/
docs/runbooks/
But documentation is not enough.
Make important rules executable.
Do not merely write:
Controllers must not execute SQL.
Add an architecture test.
Do not merely write:
Money uses integer cents.
Encode it:
<?php
declare(strict_types=1);
final readonly class Money
{
/**
* @param int<0, max> $cents
*/
public function __construct(
public int $cents,
) {
if ($cents < 0) {
throw new InvalidArgumentException(
'Money cannot contain negative cents.',
);
}
}
}
The best documentation is a system that rejects invalid construction.
Factories do not ask machines to produce “high-quality parts.”
They define tolerances.
Software needs the same thing:
Public APIs must not change.
Domain code must not depend on HTTP infrastructure.
Only repository classes may execute SQL.
No new production dependencies.
PHPStan errors must not be suppressed.
Every skipped verification command must be reported.
A vague instruction forces the model to invent its own definition of quality.
Then everybody acts surprised when it chooses convenience.
Do not ask whether the model was smart.
Ask whether the result stayed inside the tolerances.
An agent saying:
All tests pass.
is not evidence.
It is text generated by the same system that generated the code.
Require:
For a PHP project:
composer test
vendor/bin/phpstan analyse --no-progress
vendor/bin/php-cs-fixer fix --dry-run --diff
Where configured:
vendor/bin/infection --min-msi=80
The result must be explicit:
PASSED
FAILED
SKIPPED
NOT AVAILABLE
Not:
Looks good.
Not:
Should work.
Not:
I could not run the tests, but the change is straightforward.
A factory with broken gauges can produce consistently broken products.
Consistency is not correctness.
Agents assume that every task must produce a patch.
That creates ceremonial changes:
Sometimes the correct result is:
No change required.
The bug may already be fixed.
The report may be wrong.
Another service may own the failure.
The required external system may be unavailable.
The requested change may make the architecture worse.
Require reproduction first:
Reproduce the reported behavior before modifying production code.
If it cannot be reproduced:
1. Report the scenarios tested.
2. Report the commands executed.
3. Report the observed behavior.
4. Identify unavailable dependencies.
5. Do not create a diff merely to appear productive.
Evidence is progress.
A diff is not.
Reading every generated line with equal intensity is not a quality strategy.
It is an attention-distribution bug.
Spend human attention on:
Spend less attention on deterministic work protected by automation:
A decorative screw and a structural bolt do not deserve the same inspection.
That is not laziness.
That is engineering.
But there is no free shortcut:
Reading less code requires testing more behavior.
Reading less and testing less is not industrialization.
It is negligence with better branding.
Lines generated do not matter.
Tokens consumed do not matter.
The percentage of AI-written code does not matter.
Measure:
One thousand generated lines may be useful.
They may also be industrially produced waste.
Your repository is the benchmark that matters.
Not the vendor’s multiplier.
When generated code breaks production, responsibility cannot be assigned to the model.
The model does not:
A real workflow defines:
This is not new AI bureaucracy.
This is engineering accountability that should already have existed.
The machine simply exposes its absence.
Do not build a giant internal AI platform first.
That is how companies spend a year automating work they never understood.
Choose one repeatable task:
Then define:
That is already a software factory.
Small, but real.
The developer is not disappearing.
The work is moving.
Less value comes from manually typing predictable code.
More value comes from:
A master carpenter should not spend every day producing identical shelf pins.
But somebody still needs to understand material, structure, load, and failure.
Otherwise the factory produces furniture efficiently until somebody sits on it.
The same applies to software.
The agent is not the factory.
The model is not the production system.
Generated code is not automatically the product.
The factory is the system of constraints, evidence, inspection, and responsibility around the machine.
You bought the machine.
Stop admiring how fast it moves.
Build something that can reject its garbage.