Let It Cook: When AI Fixes Its Own Mess
Or: Guardrails in Action: The AI That Fixed Itself (And Documented It)
The Challenge
Section titled “The Challenge”Here’s the experiment: ask an AI agent to “fix the flaky tests” and walk away. No hand-holding. No step-by-step instructions. No hovering over its shoulder like a helicopter parent at a chess camp.
Just… let it work.
Results:
- Compute time: 10 minutes 26 seconds
- Human intervention: Minimal (initial request + final approval)
- Changes: 164 insertions, 85 deletions across 4 files
- Outcome: 6-14 random failures → 0 failures, 100% pass rate
Let’s break down how guardrails enabled this level of autonomy.
The Session Timeline
Section titled “The Session Timeline”Phase 1: Diagnosis (2m 12s)
Section titled “Phase 1: Diagnosis (2m 12s)”The agent:
- Ran full test suite once:
npm test -- --run > test-output.txt - Identified 6-14 flaky failures across 3 test files
- Analyzed failure patterns (race conditions in parallel execution)
- Discovered root cause: shared ticker symbols (
'AAPL') causing database conflicts
Guardrail in action:
# Step 1: Run ONCE and save outputnpm test -- --run > test-output.txt 2>&1
# Step 4: Run ONLY failing test filenpm test tests/api/specific-test.test.ts -- --runThe agent never ran the full suite repeatedly. It followed the guardrail: run once, analyze, target specific failures. This saved approximately five minutes of wasted compute.
Phase 2: Implementation (1m 24s)
Section titled “Phase 2: Implementation (1m 24s)”The agent:
- Designed solution: file-specific ticker symbols for isolation
- Created unique identifiers respecting database constraints (VARCHAR(10))
- Updated 3 test files with new ticker constants
- Modified cleanup logic to filter by ticker
Clean. Methodical. Almost suspiciously competent.
Phase 3: Iteration (1m 32s)
Section titled “Phase 3: Iteration (1m 32s)”First attempt failed. Ticker symbols too long (TEST_CANDLE_CACHE = 17 chars > 10 char limit).
The agent:
- Analyzed the VARCHAR constraint error
- Shortened to
TESTCC,TESTCS1-3,TESTPH - Fixed all occurrences before testing again
No flailing. No “let me try that again” with the exact same approach. Just methodical problem-solving.
Phase 4: Verification (1m 51s)
Section titled “Phase 4: Verification (1m 51s)”The agent ran the full suite three times:
- Run 1: 630/630 passed ✅
- Run 2: 630/630 passed ✅
- Run 3: 630/630 passed ✅
It knew multiple successful runs were needed to prove consistency. One passing run means nothing when you’re dealing with flaky tests.
Phase 5: Documentation (2m 53s)
Section titled “Phase 5: Documentation (2m 53s)”The agent proactively documented the solution without being asked:
## Test Isolation for Parallel Execution
**CRITICAL**: Tests run in parallel by default. Ensure proper isolation.
// ✅ CORRECT - Use file-specific test data identifiersconst TEST_TICKER = 'TESTCC'; // Unique per test file, max 10 chars
beforeEach(async () => { // Clean up ONLY this file's data await db.delete(candleCache).where(eq(candleCache.ticker, TEST_TICKER));});
// ❌ WRONG - Shared identifiers cause race conditionsconst TEST_TICKER = 'AAPL'; // Other test files may use same tickerawait db.delete(candleCache); // Wipes ALL data, breaks parallel testsPhase 6: Completion (34s)
Section titled “Phase 6: Completion (34s)”The agent:
- Created GitHub issue #116 with problem/solution description
- Committed:
fix(tests): isolate parallel test execution for #116 - Created PR #117 with detailed description
- Invoked code-reviewer subagent
All the paperwork. All the process. All without being reminded.
What Would Have Gone Wrong Without Guardrails
Section titled “What Would Have Gone Wrong Without Guardrails”The Ralph Wiggum Approach
Section titled “The Ralph Wiggum Approach”Imagine running this same task with a stateless loop and no guardrails:
The Guardrailed Approach
Section titled “The Guardrailed Approach”Phase 1: Systematic diagnosis following documented procedure Phase 2: Solution designed with constraints in mind Phase 3: Quick iteration when first attempt fails Phase 4: Verification with multiple runs Phase 5: Documentation for future benefit Phase 6: Proper issue/PR workflow with review
Time: 10 minutes Quality: Verified by tests and code review Learning: Guardrails updated for future agents
Same problem. Wildly different outcomes.
Key Guardrails That Enabled Autonomy
Section titled “Key Guardrails That Enabled Autonomy”Process Guardrails
Section titled “Process Guardrails”# Step 1: Run ONCE and save outputnpm test -- --run > test-output.txt 2>&1
# Step 4: Run ONLY failing test filenpm test tests/api/specific-test.test.ts -- --runImpact: Saved approximately five minutes by avoiding repeated full test runs.
Quality Guardrails
Section titled “Quality Guardrails”## Pre-Commit Checklist- [ ] GitHub issue exists and referenced- [ ] Tests pass- [ ] Commit follows conventional formatImpact: Agent created issue, linked commits, followed conventions. All without prompting.
Safety Guardrails
Section titled “Safety Guardrails”## Never Do This- ❌ Run full test suite repeatedly to debug- ❌ Hardcode or assume GitHub repo owner/name- ❌ Skip code review after PR creationThe “never do this” list is just as important as the “do this” list. Maybe more important.
Permission to Iterate
Section titled “Permission to Iterate”If you encounter repeat failures doing the same thing, explain whatyou think might be happening, and try another approach.Impact: Agent tried multiple approaches without giving up after first failure. It had explicit permission to fail, learn, and try again.
Results
Section titled “Results”| Metric | Before | After |
|---|---|---|
| Pass rate | 98.7-99.2% | 100% |
| Random failures | 6-14 | 0 |
| Test duration | ~7-9s | ~8-9s (no impact) |
| Consistency | Flaky | 3+ perfect runs |
Plus: comprehensive documentation added to AGENTS.md for future reference.
The Autonomy Spectrum
Section titled “The Autonomy Spectrum”This session demonstrates high autonomy:
Low Autonomy High Autonomy│────────────────────────────────────────────────────────────││ ✓ │Micromanaged Guided Supervised Autonomous(step-by-step) (with hints) (check-ins) (goal-oriented)What made this possible:
- Clear goal: “Fix the flaky tests”
- Comprehensive guardrails: AGENTS.md with 400+ lines
- Tool access: Git, GitHub API, file operations, test execution
- Feedback loops: Test results, git status, diagnostics
- Trust boundaries: Agent can commit/push, human approves merge
The agent had everything it needed to succeed. And crucially, it had constraints that prevented it from doing something catastrophically stupid.
Lessons Learned
Section titled “Lessons Learned”Guardrails Enable, Not Restrict
Section titled “Guardrails Enable, Not Restrict”Bad guardrail: “Always use AAPL as the test ticker symbol.” Good guardrail: “Use file-specific test data identifiers to prevent race conditions.”
The good guardrail explains the principle and provides an example, but lets the agent choose specifics. It’s the difference between “paint this wall blue” and “make sure the wall color complements the furniture.”
Document the “Why”
Section titled “Document the “Why””The agent added:
### Why Not Use Transactions?
While transaction rollback isolation seems ideal, it has drawbacks:- Requires complex transaction context management- Interferes with code that uses its own transactions- Harder to debug when tests fail
**File-specific identifiers are simpler, faster, and more reliable.**This isn’t just a solution. It’s decision documentation. Future agents won’t waste time re-exploring rejected alternatives.
Checklists Beat Instructions
Section titled “Checklists Beat Instructions”Instead of prose instructions, use scannable checklists:
## Pre-Commit Checklist- [ ] GitHub issue exists and referenced- [ ] Tests pass- [ ] Commit follows conventional formatChecklists are non-linear. The agent can verify nothing was missed. Prose instructions are easy to skim and miss details.
The Guardrail Paradox
Section titled “The Guardrail Paradox”More structure enables more freedom.
This sounds backwards until you think about it. By providing comprehensive guardrails, we enabled the agent to work completely autonomously for 10 minutes. No hand-holding. No micromanagement.
The agent diagnosed a complex race condition, tried multiple solutions, implemented the optimal fix, verified it worked, documented the pattern, created an issue and PR, and invoked code review.
All without a single human intervention.
The guardrails didn’t restrict the agent. They gave it the confidence to act. They provided the boundaries within which it could operate freely. Like bumpers at a bowling alley. You’re not limiting the game. You’re making it possible to play without constant gutter balls.
This is the future: humans set goals, guardrails guide execution, AI agents do the work, and the system gets smarter with each problem solved.
See Effective AI-Augmented Development for the full framework, or Scaling to Parallel Agents for running multiple agents simultaneously.