Ralph Wiggum Explained: Stop Telling AI What You Want — Tell It What Blocks You

6 min read Original article ↗

Everyone’s hyped about the Ralph Wiggum technqiue for Claude Code.

Install it. Write a prompt. Let AI work autonomously for hours. Come back to a finished app. Sounds incredible.

Here’s what actually happens: You write a prompt. Ralph runs for 45 minutes. It declares victory. You check the output. Half the requirements are missing. iOS doesn’t compile. The “persistence” layer saves to memory that vanishes on restart.

What went wrong? Nothing, actually.

Ralph did exactly what you asked. The problem is what you asked for.

Why "Better Prompts" Doesn't Help

The standard advice is “write better prompts.” More detail. More specificity. That’s like saying “write better requirements” when your app has bugs. True, but useless.

Here’s the non-obvious part: Ralph Wiggum is a loop. It runs, checks your success criteria, and keeps going until all criteria pass. That’s it. That’s the whole trick.

Which means everything depends on the criteria. Vague criteria? Ralph satisfies them vaguely and stops. You asked for “app works on all platforms.” It ran on desktop once, saw no crash, declared success. Technically correct.

The skill isn’t “prompt engineering.” It’s criteria design. And there’s a much simpler way to think about it.

Part 1 This is Part 1 of a series on building Uno Platform apps with Studio and a Ralph Loop workflow. The big idea in this post: constraints beat instructions.

The Reframe: Constraints, Not Wishes

Forget what you want. Focus on what would block your PR.

You already know this list:

  • Does it build on iOS?
  • Does it build on Android?
  • Do the analyzers pass?
  • Are there warnings?
  • Does the app actually launch?

These are constraints. Binary. Pass or fail. No interpretation required.

Ralph’s success criteria should be the same thing. Not “works correctly” but “`dotnet build -f net10.0-ios` exits 0.” Not “follows best practices” but “no classes implement INotifyPropertyChanged in the Models folder.”

This is the entire insight. Convert wishes into gates.

The Test: Can a Script Check It?

Here’s a simple filter. For each success criterion, ask: “Can a script verify this?”

If yes, it’s a constraint. If no, it’s a wish.

Wish Constraint
"Works on iOS" dotnet build -f net10.0-ios exits 0
"Uses MVUX correctly" IState<T> found in Model classes
"Responsive design" VisualStateManager defines states at 641px and 1008px
"Data persists" File exists at specific path after app restart
"Good UX" All touch targets MinHeight >= 44

Ralph can grep. Ralph can run build commands. Ralph can check file existence. Ralph cannot evaluate “good.”

Every wish becomes a gate. Every gate is binary. That’s the whole approach.

Three Examples That Actually Work

Let me show you weak criteria, what goes wrong, and how to fix them. All three are Uno Platform scenarios because that’s what I work with, but the pattern applies anywhere.

01 Cross-Platform Build

The Task

Create an Uno Platform app with TabBar navigation.

❌ What you might write

App works on all platforms

No major errors

Navigation functions correctly

✅ What actually works

dotnet build -f net10.0-ios exits 0, zero warnings

dotnet build -f net10.0-android exits 0, zero warnings

dotnet build -f net10.0-desktop exits 0, zero warnings

dotnet build -f net10.0-browserwasm exits 0, zero warnings

TabBar contains min 3 TabBarItem elements in XAML

Each TabBarItem has distinct Content page

No TODO comments in generated code

What happens with vague criteria → Ralph builds it. Runs it once on desktop. Tabs switch. No crash visible. Done. Three weeks later you try the iOS build. Linker error. Android crashes on startup.

02 MVUX State Management

The Task

Implement user preferences with MVUX and persistence.

❌ What you might write

MVUX pattern implemented correctly

Settings persist between sessions

UI updates reactively

✅ What actually works

PreferencesModel.cs uses IState<UserPreferences>

No classes implement INotifyPropertyChanged in Models

Settings serialized to LocalFolder/preferences.json

Persistence test: write, terminate, restart, read

Zero binding errors in debug output

Uno.Extensions.Reactive in csproj

What happens with vague criteria → Ralph uses INotifyPropertyChanged instead of IState<T> because that's more common in training data. Saves settings to a dictionary in memory. "Persists" until you close the app.

03 Responsive Layout

The Task

Dashboard that adapts from mobile to desktop.

❌ What you might write

UI is responsive

Looks good on phone and desktop

Sidebar collapses on small screens

✅ What actually works

VisualStateManager: Compact, Medium, Expanded

AdaptiveTrigger: MinWindowWidth 0, 641, 1008

NavigationView.PaneDisplayMode changes per state

No hardcoded Width in pixels (use Auto or *)

All interactive elements: MinHeight ≥ 44, MinWidth ≥ 44

No horizontal scrollbar at any breakpoint

What happens with vague criteria → Ralph adds Grid columns with arbitrary breakpoints. "Responsive" technically achieved. "Looks good" evaluated by nobody. Sidebar disappears entirely or overlaps content.

The Constraint Stack

Here’s how I build success criteria now. Four layers, in order:

1 Build Gates

dotnet build -f net10.0-ios exits 0

dotnet build -f net10.0-android exits 0

dotnet build -f net10.0-desktop exits 0

dotnet build -f net10.0-browserwasm exits 0

2 Type Contracts

Required types exist where expected (IState

, IFeed, interfaces)

Anti-patterns are absent (no INotifyPropertyChanged, no ObservableCollection)

NuGet packages referenced

3 Structural Contracts

Required files exist at expected paths (Models/Task.cs, Services/ITaskService.cs)

Patterns present in specific files (uen:Navigation.Request in page XAML)

Folder structure matches architecture (no code-behind navigation calls)

4 Runtime Verification Contracts

App launches without exception

Specific behavior verified (nav, persistence)

Debug output clean

Stack these. Ralph checks all of them, every loop. If it doesn’t compile on all targets, nothing else matters.

Runtime verification We'll cover runtime UI verification via App MCP screenshots and visual tree inspection in more depth later in this series.

Iteration Budget: A Real Tradeoff

The --max-iterations flag matters more than people realize.

Loose criteria with high iteration cap: Ralph loops forever trying to satisfy something unmeasurable. Burns your usage. Produces garbage. Tight criteria with reasonable cap: Ralph converges fast because exit conditions are clear. 30 iterations is usually enough for a well-specified task.

Tight criteria reduce iteration count, which reduces cost. Vague criteria do the opposite. 

What This Doesn't Fix

Let me be direct about limitations.

Aesthetic judgments: “Looks good” requires eyes. Constrain structure, review visuals yourself.

Performance at scale: “Handles 10K items” or “loads in under 2 seconds” requires load testing. Ralph can build it. You benchmark it.

Security vulnerabilities: XSS, injection, exposure of secrets. Ralph doesn’t audit for these. Run your security tooling separately.

Business logic correctness: “Calculates tax correctly” or “handles edge cases” requires domain knowledge. Constrain the structure, verify the math yourself.

Integration complexity: External APIs, authentication flows, device-specific behavior. Ralph can scaffold. You verify.

The judgment problem: Some decisions are subjective. Ralph will make choices. You might disagree. That’s not a bug.

The pattern: constrain what you can (structure, types, patterns), review what you can’t (aesthetics, security, business logic). 

Remember Autonomous doesn't mean unsupervised. Know when to stop Ralph and review.

Takeaway

Ralph Wiggum isn’t magic. It’s a loop with a termination condition. Your success criteria are that condition.

Vague criteria produce vague results. Binary constraints produce verifiable results. The skill is converting what you want into what can be checked

You already do this for CI pipelines. Do the same thing for Ralph.

Shoutout

Shout out to Geoffrey Hutley, the creator of Ralph and a former contributor to Uno Platform project a few years ago — thanks for building Ralph and pushing the space forward.