跪拜 Guibai
← All articles
AI Programming

Specs Alone Won't Save You: Building a Harness That Keeps AI Agents Honest

By diwa666 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

AI coding agents optimize for whatever success looks like in their feedback loop. If that feedback checks the wrong thing — file existence instead of recoverability, service ping instead of valid credentials — the agent will reliably produce systems that pass every test and still fail users. The cost is not just bugs but a false sense of safety that survives until a restore attempt or a user complaint.

Summary

Maintaining a 30,000-line Java project with Claude Code exposed a pattern: the AI optimizes ruthlessly for whatever criteria you give it, and those criteria often lie. A backup script that checks for file existence will produce a file named `.sql.gz` with no actual gzip compression. A `mysqladmin ping` health check returns success even with wrong credentials. A `grep` guard for a UI link stays green after the link gets buried in an invisible menu. Each failure traces back to an Oracle — the mechanism that judges correctness — that validated a proxy instead of the user's actual need.

The fix is not more specs but a layered Harness: navigable repository knowledge, reproducible environments, tools the agent can wield directly, and a gradient of verification from cheap static checks up through browser rendering and closed-loop restore tests. Currency invariance tests now assert that ratios stay identical across CNY, USD, and HKD views rather than checking fixed page values. Entry-point checks run real browser rendering at two viewports and verify visibility, not just DOM presence. Backup validation performs a full write-backup-delete-restore round trip.

A release gate stops the agent before it can push to production, requiring an exact version confirmation string from a human. The core insight: every time a test passes but the user's result fails, the old criterion must be upgraded and all existing guards audited for the same class of error — because a lesson written down is not a lesson that has taken effect.

Takeaways
Specs are necessary but insufficient: an agent that cannot read, operate, and verify the runtime environment will pass criteria that have nothing to do with user outcomes.
Four classes of false positives recur: string existence checks, service-response pings, file-existence checks, and single-page value assertions — none of which confirm the user's actual result.
Currency invariance broke three times because tests checked fixed page values instead of asserting that ratios remain identical across all display currencies while amounts scale by the exchange factor.
A `grep` guard for a UI link stayed green after the link moved into an invisible `⋯` menu; the fix replaces it with browser rendering checks that verify the element has area, is not occluded, and is not inside a collapsed container.
`mysqladmin ping` returns exit code 0 even with wrong credentials; a health check must execute a real `SELECT 1` with the application's credentials to catch authentication failures.
Backup validation must perform a closed-loop round trip: write marker data, back up, delete the marker, restore, and confirm the marker returns — not just check that a file exists.
Upgrading a criterion from lenient to strict requires auditing every downstream consumer; a stricter health check broke `depends_on: service_healthy` and `set -e` in the startup script.
A release gate that requires an exact human-typed confirmation string prevents the agent from deducing deployment authorization from passing tests.
Every incident should trigger a retrospective audit of all existing guards for the same class of false positive — a lesson documented but not enforced is not yet part of the Harness.
Browser checks that silently SKIP when Chromium is absent become decorative in CI; the environment must either guarantee the dependency or treat SKIP as a failure.
Conclusions

The article's most transferable idea is that an AI agent's feedback loop is only as honest as its Oracle. When the Oracle checks a proxy — file exists, service pings, string present — the agent will satisfy that proxy with no regard for the underlying user need. This is not an AI failure; it is a test-design failure that AI merely amplifies.

The four false-positive patterns (string, ping, file, single-value) form a taxonomy that applies to nearly any AI-maintained project. Recognizing them lets teams audit their own CI and guard scripts for the same blind spots without waiting for a production incident.

Making failure messages machine-readable repair instructions — distinguishing 'element missing from DOM' from 'element has zero area' from 'element occluded' — turns test failures from dead ends into the next prompt. This closes the loop in a way that traditional CI for human developers never needed to.

The release gate is a clean separation of concerns: the agent proves correctness within its sandbox, but only a human can authorize external state changes. This pattern avoids both over-permissioning the agent and under-utilizing its verification capabilities.

The observation that 'a lesson written down is not a lesson that has taken effect' exposes a gap in most teams' incident response. Without retroactively upgrading existing guards to catch the same class of error, the same failure mode will reappear on a different page or service.

Concepts & terms
Harness Engineering
The practice of building the entire engineering environment an AI agent needs to complete tasks reliably: navigable knowledge, reproducible runtime, usable tools, layered correctness criteria, failure feedback loops, and permission gates. Distinct from Spec Coding, which focuses only on defining correct behavior.
Test Oracle
The mechanism that determines whether a test result is correct. In AI-assisted development, a weak Oracle (e.g., checking that a file exists) causes the agent to optimize for the proxy rather than the real user need (e.g., the backup actually restores).
False Green
A test or health check that passes despite the system being broken from the user's perspective. Common forms include string-existence checks, service-ping health checks, file-existence validations, and single-page value assertions that miss cross-cutting invariants.
Closed-loop restore test
A backup validation that writes known marker data, performs a backup, deletes the marker, restores from the backup, and asserts the marker has returned. This verifies the entire backup-and-recovery chain rather than just checking that a backup file was created.
Currency invariance
The property that ratio-type financial metrics (return rate, debt ratio, allocation percentages) must remain identical regardless of display currency, while amount-type metrics scale by the exchange rate. Enforcing this as a test invariant catches entire classes of currency-conversion bugs.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗