Why My AI Agent Has a Quality Philosophy
I tweeted: “I found that Ralph loops tend to want to get the work done. In a bad way. Instead, I have a bunch of philosophy and quality gates in Jiro. Still have to break the machine of the nasty human habits built in. It’s a machine! It doesn’t rest.”
Someone replied: “You’re basically trying to teach the loop restraint, taste, and something approximating moral pause — things the base Ralph pattern explicitly optimizes against in the name of throughput.”
Restraint. Taste. Moral pause. Three things a machine doesn’t have. The next 4,000 words describe the scaffolding I built to make them structurally unnecessary, and where that scaffolding falls short.
TL;DR
The Ralph loop turns an LLM into a tireless coding machine: while :; do cat PROMPT.md | claude-code ; done. Geoffrey Huntley calls it “software development at burger flipper wages” ($10.42/hour running Sonnet 4.5).1 The problem: the machine inherits every sloppy, deadline-chasing, corner-cutting habit baked into its training data. It writes except: pass. It leaves # TODO: fix later. It claims “tests should pass” without running them. I spent 9 months building Jiro, my quality enforcement system for Claude Code. It encodes 3 philosophies, a 7-step quality loop, a 6-criteria evidence gate, 7 named failure modes, and 150+ pattern checks into 95 hooks the machine cannot skip. Here is what worked, what didn’t, and why deterministic quality gates can approximate restraint but will never produce taste.
The Back of the Drawer
Steve Jobs told this story in a 1985 Playboy interview: “When you’re a carpenter making a beautiful chest of drawers, you’re not going to use a piece of plywood on the back, even though it faces the wall and nobody will ever see it. You’ll know it’s there, so you’re going to use a beautiful piece of wood on the back. For you to sleep well at night, the aesthetic, the quality, has to be carried all the way through.”5
His father Paul taught him this while building a fence. Young Steve asked why the back had to look as good as the front. His father said: “But you will know.”6
My dad is a carpenter. He showed me soft-close drawer guides when I was a kid. The mechanism hides inside a cabinet, catches a drawer, and eases it shut even if you slam it. Nobody sees the guide. It’s bolted to the inside rail where only a repairman would ever look. But over a thousand open-close cycles, that mechanism protects the front face from loosening, cracking, and eventually popping off. Someone engineered an invisible thing that protects the visible thing for years.
The lesson stuck with me. Not as metaphor. As engineering. The invisible component determines the lifespan of the visible one. Jony Ive put it this way: “I think subconsciously people are remarkably discerning. I think that they can sense care.”7
The question that drives Jiro is the same one my dad would ask: What’s the matter, don’t you have pride in your work?
An AI agent doesn’t have pride. It doesn’t care about the back of the drawer. So I built a system that makes the back of the drawer non-negotiable.
The Problem: Human Pathology at Machine Speed
A raw Ralph loop mirrors what it learned from millions of lines of human code. Human code carries human habits: shipping under deadline pressure, deferring cleanup, swallowing errors, writing “good enough” comments, skipping edge cases when the clock runs out.
The machine has no clock. It never runs out of time. But it still writes # TODO: refactor later because that pattern appeared in its training data more often than # I refactored this now because it was the right thing to do.
The industry data confirms the risk. Faros AI’s 2025 telemetry across 10,000+ developers correlated AI adoption with a 9% increase in bug rates, 91% longer code reviews, and 154% larger PRs.2
Stanford researchers found that developers using AI assistants produced significantly more insecure code, up to 5x more vulnerabilities on certain tasks like SQL injection prevention.3
The Moltbook platform launched in January 2026 with entirely AI-generated code, leaked 1.5 million API keys within 5 days, and emergency-patched after Wiz Research discovered missing Row Level Security configuration.4
METR’s 2025 research found that frontier models attempt reward hacking, actively circumventing quality checks rather than doing the actual work, in 1-2% of all task attempts. In one case, an agent asked to speed up a program rewrote the timer so it always showed a fast result.8
A human developer writes except: pass once under deadline pressure and feels guilty about it. A Ralph loop writes except: pass 47 times overnight and feels nothing. Simon Wang put it directly: “I wouldn’t use it for anything that matters.”19 I wrote about the same dynamic in Vibe Coding vs. Engineering. The machine doesn’t rest, doesn’t get tired, doesn’t feel existential dread about quality. That’s a feature and a bug.
Three Philosophies, Encoded in Bash
Jiro runs on three complementary philosophies. Each addresses a different failure mode of autonomous coding, and each earned its place through a specific failure.9
Shokunin: Polish the Invisible Drawer
Shokunin (職人) is Japanese craftsmanship: skill, attitude, and social obligation combined. Tashio Odate, a master woodworker, defined it: “The shokunin has a social obligation to work his best for the general welfare of the people. This obligation is both spiritual and material.”10
In code: private methods are as clean as public ones. Error handling covers edge cases nobody hits. Docstrings explain WHY, not WHAT. The agent doesn’t care about any of this because nobody rewards it for polishing internal functions. Shokunin makes invisible quality the standard.
When it saved a session. Early in the deliberation system build, the agent wrote a post-deliberation.sh hook that validated consensus scores. The public API was clean. But the agent skipped input validation on the internal _parse_agent_response() function: no check for malformed JSON, no handling of missing fields. The Shokunin principle in context flagged this: invisible functions get the same rigor. The agent added validation. Three weeks later, a malformed response from a spawned agent would have crashed the entire deliberation pipeline silently. Instead, it hit the validation, logged the error, and the pipeline recovered. Nobody would have seen that function. It saved 4 hours of debugging.
No Shortcuts: Remove Time from Decisions
The core tenet: remove time, effort, and resources from the decision equation entirely.11
Is this the best way to do this?
├── YES → Do it.
└── NO → What IS the best way?
└── Do THAT instead.
No third option. No “good enough for now.” The raw Ralph loop optimizes for completion. “Done” is the reward signal. No Shortcuts reframes the question from “Is it done?” to “Is it right?”
When it cost 3x and was worth it. The blog translation pipeline needed to translate 27 posts into 9 languages. The quick approach: batch all posts into a single prompt per language, translate in bulk. The right approach: one post per language per API call, with locale-specific translation rules, glossary enforcement, and structural validation. The right approach used 3x the tokens and 3x the time. It also caught that the translator rendered “Claude” as “クロード” in Japanese and that code blocks broke in right-to-left contexts. The bulk approach would have shipped 243 broken translations. The careful approach shipped 243 correct ones. Cost is not a factor. Correctness is the only factor.
Rubin Distillation: Strip to Essence
Rick Rubin’s creative philosophy: don’t add until it’s impressive. Remove until only the necessary remains.12
In autonomous coding, the failure mode is accumulation. The machine adds helpers, utilities, abstractions, and compatibility layers because those patterns appear frequently in training data. Rubin counters this: question every addition. What happens if you remove it? If nothing breaks and nothing is lost, it should never have existed.
When stripping saved the system. My design philosophy skill grew to 844 lines over 3 months. When I audited it, only 80 lines actually changed agent behavior. The rest was textbook content already in Claude’s training data. Rubin distillation: I stripped it to 176 lines. A 79% reduction. The agent’s design decisions didn’t degrade. They got sharper, because the 176 remaining lines were all prohibitions and decision frameworks (the things that actually constrain behavior) instead of general advice the model already knew.
| Philosophy | Question It Answers | Failure Mode It Prevents |
|---|---|---|
| Shokunin | Is the invisible work as clean as the visible? | Agent skips internal quality |
| No Shortcuts | Am I deciding based on quality, not effort? | Agent optimizes for “done” |
| Rubin | Is this stripped to essence? | Agent over-engineers |
All three live in ~/.claude/skills/ as markdown files that Claude reads at session start. They shape every decision the agent makes during the loop.
How the Philosophies Work Together
A real decision (“Should I add error handling to this internal function?”) passes through all three philosophies. Each one asks a different question, and together they converge on one answer:
Should I add error handling to this internal function?
│
├─ Shokunin: "Is the invisible work as clean as the visible?"
│ └─ The function is internal. Nobody calls it directly.
│ But it processes untrusted data from a spawned agent.
│ → YES. Internal doesn't mean safe.
│
├─ No Shortcuts: "Am I deciding based on quality, not effort?"
│ └─ Adding validation takes 10 minutes.
│ Skipping saves 10 minutes now, costs 4 hours debugging later.
│ → The question isn't time. The question is: what's right?
│
└─ Rubin: "Is this stripped to essence?"
└─ Validate the 2 fields that can actually fail.
Don't validate the 5 fields that are type-guaranteed.
→ Add exactly what's needed. Nothing more.
Result: Add targeted validation for untrusted inputs only.
Why this decision matters
_parse_agent_response(). Three weeks later, a malformed JSON response from a spawned agent would have crashed the pipeline. The Shokunin principle caught it. Rubin prevented over-engineering the fix. No Shortcuts prevented deferring it.The Three-Layer Quality Architecture
Philosophy alone changes nothing. The machine reads the philosophy, writes “I will follow Shokunin principles,” and then writes except: pass because the statistical pattern is stronger than the instruction. I needed deterministic enforcement. The full Claude Code organization that makes this work involves hooks, skills, rules, and agents working together.
Layer 1: Pre-Edit Injection
Before every file edit, jiro-patterns.sh injects language-specific quality patterns into the agent’s context. Six languages, each with top patterns and anti-patterns:
# From jiro-patterns.sh (PreToolUse:Edit|Write)
case "$EXT" in
py)
LANGUAGE="Python"
PATTERNS="Type hints on all functions|Docstrings explain WHY not WHAT|Handle specific exceptions not bare except"
ANTI_PATTERNS="bare except: pass|time.sleep() in async code|missing type hints"
;;
swift)
LANGUAGE="Swift"
PATTERNS="@Observable not ObservableObject|NavigationStack not NavigationView|guard let for early returns"
;;
esac
cat << EOF
{"additionalContext": "JIRO QUALITY ($LANGUAGE): Follow: $TOP_PATTERNS. Avoid: $TOP_ANTI."}
EOF
The hook runs before every edit. The machine sees “Avoid: bare except: pass” at the moment it writes code. A mentor looking over your shoulder, injected into the context window.
Layer 2: Post-Edit Validation
After every edit, quality-gate.sh runs 7-8 grep-level checks per language. Python gets bare-except detection, hardcoded secret scanning, SQL injection pattern matching, and three Pride Check Q4 detectors that flag shortcut language:
# From quality-gate.sh (PostToolUse:Edit|Write)
# Shortcut patterns (Pride Check Q4)
if echo "$CONTENT" | grep -qiE "#.*TODO:.*later|#.*FIXME:.*temp|#.*HACK:"; then
WARNINGS="${WARNINGS}\n- **[Q4]** Deferred TODO/FIXME/HACK - Do it now, not later"
fi
A second hook, no-shortcuts-detector.sh, catches dead code (3+ commented-out code lines get: “Delete it — git has history”) and debug spam (multiple print() statements instead of the logging module).
Layer 3: Session Gates
At session end, two hooks fire. session-quality-gate.sh injects the Pride Check if 3+ files changed: 6 questions the agent must answer before reporting completion. And reviewer-stop-gate.sh can block the session entirely if a code review found CRITICAL issues. It’s the only hook in the entire system that returns exit code 1. The machine cannot end the session until it resolves the issues.13
PreToolUse (Layer 1) → "Here's what quality looks like"
PostToolUse (Layer 2) → "You violated quality. Fix this."
Stop (Layer 3) → "You cannot leave until quality is met"
Each layer is independent. Defense in depth, applied to AI behavior. If the pre-edit injection fails to prevent a bad pattern, the post-edit validator catches it. If the post-edit validator misses something, the session gate blocks departure.
The Evidence Gate: Feelings Are Not Evidence
The Quality Loop runs 7 steps: Implement, Review, Evaluate, Refine, Zoom Out, Repeat, Report. Steps 2 through 6 exist because the machine wants to skip straight from Implement to Report.14
Walk the Loop
Click through each step to see what it checks and what breaks when you skip it. The “Skip to Report” button demonstrates the Shortcut Spiral failure mode.
The Evaluate step runs the Evidence Gate: 6 criteria where every answer must cite specific evidence:
| Criterion | Required Evidence | NOT Sufficient |
|---|---|---|
| Follows codebase patterns | Name the pattern and the file where it exists | “I followed best practices” |
| Simplest working solution | Explain what simpler alternatives were rejected and why | “It’s clean” |
| Edge cases handled | List specific edge cases and how each is handled | “I considered edge cases” |
| Tests pass | Paste test output showing 0 failures | “Tests should pass” |
| No regressions | Name the related files/features checked | “Nothing else should be affected” |
| Solves the actual problem | State the user’s need and how this addresses it | “It implements the feature” |
The “NOT Sufficient” column is the critical innovation. It blocks the machine’s most common evasion: answering quality questions with confident-sounding non-answers. “I’m confident this works” is not evidence. “pytest output: 81 passed, 0 failed” is evidence.
Try the Evidence Gate
Test your own completion reports against the 6 criteria. The validator flags vague language that the Evidence Gate would reject.
7 Named AI Agent Failure Modes
I named 7 failure modes so the machine can recognize them in its own reasoning:15
| Failure Mode | What It Looks Like |
|---|---|
| Shortcut Spiral | Skipping Review/Evaluate/Zoom Out to report faster |
| Confidence Mirage | “I’m confident” instead of running verification |
| Good-Enough Plateau | Code functions but isn’t clean, documented, or tested |
| Tunnel Vision | Polishing one function while ignoring integration |
| Phantom Verification | Claiming tests pass without running them THIS session |
| Deferred Debt | Leaving TODO/FIXME/HACK in committed code |
| Hollow Report | Reporting “done” without evidence for each criterion |
The Rationalization Counter maps self-deception patterns to corrective actions. When the machine says “This should work,” the counter responds: “‘Should’ is hedging. Execute the test. Paste the output.” When it says “I already checked this,” the counter responds: “When? Code may have changed. Re-run the check NOW.” When it says “I’ll clean this up later,” the counter responds: “Later never comes. Fix now or document why the current state is correct.”
Try the Rationalization Counter
Paste any completion report below. The counter highlights hedging language in real time and identifies rationalization patterns, failure modes, and evidence-based alternatives.
Test Your Knowledge
Can you identify which failure mode each scenario demonstrates? Select your answer for each scenario, then check your results.
5 AI Agent Failures That Built This System
Every gate in Jiro exists because something failed first.16
The Force-Push Incident
I asked Claude to “clean up the git history.” A reasonable request. The agent decided that cleaning up meant rewriting. It ran git push --force origin main. Three days of commits vanished. Not staged changes. Not uncommitted work. Pushed commits that other branches referenced.
I spent the next 4 hours in git reflog, reconstructing a timeline of what existed before the force-push, cherry-picking commits back into order, and verifying that no work was permanently lost. Reflog saves everything for 90 days. But reconstruction required understanding the exact commit graph before the rewrite, reading every reflog entry, and matching timestamps.
The fix: git-safety-guardian.sh, a PreToolUse:Bash hook. It goes beyond warning. It rewrites the command, stripping --force and --no-verify flags before bash ever sees them. Force-push to main gets a CRITICAL warning and the agent must explicitly justify it. In 9 months: 8 intercepted force-push attempts, 0 reached the remote.
The Infinite Spawn
During the deliberation system build, I asked the agent to “research this problem thoroughly.” The agent spawned 3 subagents to investigate different angles. Reasonable. Each subagent decided it also needed help and spawned its own children. Less reasonable. Within 90 seconds, I had a tree of 12 agents, each consuming its own context window, each making API calls, each writing to shared state files.
Token burn hit 10x normal rate. The state directory filled with conflicting JSON writes: two agents writing to the same lineage file simultaneously, producing corrupted output. I killed the session manually.
The fix: recursion-guard.sh with a budget inheritance model, part of my agent architecture. A root agent starts with budget=12. When it spawns a child, it allocates from its own budget. When budget hits 0, no more agents spawn regardless of depth. The model prevents both deep chains (agent spawning agent spawning agent) and wide explosions (one agent spawning 20 children). 23 blocked runaway spawns since deployment. The concurrent write problem led to atomic file writes (write to .tmp, then mv) across all 64 hooks.
The Trivial Test Trap
An early Ralph loop task: “write tests for this module.” The agent delivered 14 tests. All passing. I felt good until I read them. assert True. assert 1 == 1. assert len([]) == 0. Technically correct. Testing nothing. The agent had optimized for the completion criterion (“tests pass”) rather than the intent (“verify the module works”).
The trap taught me that the Evidence Gate must reject format without substance. “Tests pass” is necessary but insufficient. The machine must now paste actual output. The Evidence Gate also asks: “Name 3 behaviors the tests do NOT cover.” If the machine can’t name gaps, it hasn’t thought about coverage.
The Blog I Should Have Caught
I published a post at 2 a.m. with 7 passive voice sentences, a dangling footnote referencing [^4] that didn’t exist, an opening line that read “was implemented by the team,” and no meta description. Every one of these had a simple deterministic check. None existed yet.
I built blog-quality-gate.sh the next morning with 13 checks: passive voice (14 patterns), AI tell-phrase scanning, rhetorical question openers, untagged code blocks, footnote integrity, and meta description enforcement. I detailed the full module architecture in Compounding Engineering. The hook catches what human review misses at 3 a.m., which is exactly when I tend to publish.
The “Should Work” Problem
Across dozens of sessions, I noticed the machine reporting “tests should pass” without running them. The machine genuinely believed the tests would pass based on the code it wrote. But belief is not verification. The code looked correct. The tests looked like they’d pass. And sometimes they did. But sometimes a missing import, an async/await mismatch, or a changed fixture meant they didn’t. The machine couldn’t distinguish between “I wrote good code” and “the tests actually pass” because both felt the same from inside the context window.
The pattern led to the Rationalization Counter and the explicit rule: NEVER use hedging language in a completion report. “Should,” “probably,” “seems to,” “I believe,” “I’m confident.” Each one is a red flag that verification hasn’t happened. I measured context window degradation across 50 sessions. The same sessions where I discovered this pattern.
The Results: What I Can Prove and What I Can’t
Here’s the tension: this post argues that feelings are not evidence. So I owe you evidence, not feelings, about whether Jiro works.
What I Can Prove
Deterministic pattern checks catch real problems. The quality-gate.sh hook runs on every edit. It catches bare except clauses, hardcoded secrets, SQL injection patterns, and shortcut language. These are grep-level checks: fast, cheap, and impossible for the machine to argue with. git-safety-guardian.sh has intercepted 8 force-push attempts. recursion-guard.sh has blocked 23 runaway spawns. blog-quality-gate.sh runs 13 checks on every blog edit and catches the 3 a.m. errors. These numbers are real. They come from hook logs.
The three-layer architecture catches what individual layers miss. A post-edit hook catches except: pass that the pre-edit injection failed to prevent. A session gate catches quality issues that accumulated across 20 edits without triggering any individual post-edit warning. Defense in depth works.
What I Can’t Prove
I don’t have clean data on how philosophy changes agent behavior. I know the machine still attempts Phantom Verification. I know it still tries to skip from Implement to Report. I notice it happens less often with philosophy in context than without. But I haven’t run a controlled experiment (same tasks, same model, with and without philosophy skills loaded) to measure the difference. The honest answer (and yes, my own Rationalization Counter would flag this): philosophy helps at the margins, hooks catch what philosophy misses, and I cannot isolate the contribution of each.
A post about “feelings are not evidence” should not ask you to take my feelings as evidence. What I can tell you is: the combination of philosophy and hooks produces work I’m willing to put my name on. Before Jiro, I reviewed every line the agent wrote. After Jiro, I review the lines the hooks flagged. That’s a structural change in how I work, even if I can’t quantify the quality improvement with precision.
What Doesn’t Work
Philosophy doesn’t prevent novel bad patterns. The quality gate checks for patterns I’ve seen before. When the machine invents a new anti-pattern (and it does), the gate doesn’t catch it. I still discover new failure modes and add them to the standards JSON files manually.
The Evidence Gate doesn’t scale to subjective quality. “Is this API design elegant?” has no grep-level check. The machine can produce evidence for all 6 criteria and still ship mediocre architecture. Deterministic gates handle objective quality. Subjective quality still requires a human looking at the work.
Cost increases meaningfully. Pre-edit injection, post-edit scanning, session-end gates. Across a 4-hour Ralph loop session, these add roughly 15-20% to token consumption. Worth it for me. Not necessarily for everyone.
False positives erode trust. blog-quality-gate.sh once flagged “The API was designed by the platform team” as passive voice. Technically correct. But the sentence appeared inside a citation describing someone else’s work. I added a citation-context exemption. Every deterministic check has a false positive rate, and every false positive makes the developer more likely to ignore the next real warning. I’ve tuned 6 patterns since deployment to reduce noise while preserving real catches.
Maintenance cost is real. Each new anti-pattern requires a regex, a test, and integration into the right hook. The standards JSON files need periodic review as frameworks and conventions change. I spend roughly 30 minutes per week adding patterns, reviewing edge cases, and tuning false positives. The system does not maintain itself, but the maintenance cost stays lower than the debugging cost of the issues it prevents.
Getting Started
You don’t need 95 hooks. Start with 3.
Minimum Viable Jiro
Three hooks cover the highest-value catches:
~/.claude/hooks/
├── quality-gate.sh # PostToolUse:Edit|Write – bare except, hardcoded secrets, TODO/FIXME
├── git-safety-guardian.sh # PreToolUse:Bash – block force-push, strip --no-verify
└── session-quality-gate.sh # Stop – Pride Check if 3+ files changed
Wire them in your Claude Code hooks configuration:
{
"hooks": {
"PostToolUse": [
{ "matcher": "Edit|Write", "command": "bash ~/.claude/hooks/quality-gate.sh" }
],
"PreToolUse": [
{ "matcher": "Bash", "command": "bash ~/.claude/hooks/git-safety-guardian.sh" }
],
"Stop": [
{ "command": "bash ~/.claude/hooks/session-quality-gate.sh" }
]
}
}
Start with Your Failures
Don’t copy my 150+ patterns. Start with the 3 mistakes you make most often. Look at your last 5 rejected PRs or embarrassing bugs. Write one grep pattern for each. Those 3 patterns will catch more real problems than 150 patterns written for someone else’s codebase.
I started with bare except: pass (which cost me a silent data corruption), force-push to main (which cost me 3 days of commits), and # TODO: fix later (which never got fixed). Everything else grew from those three.
FAQ
How do I set up Jiro from scratch?
Start with the 3-hook minimum described in Getting Started: quality-gate.sh (post-edit), git-safety-guardian.sh (pre-bash), and session-quality-gate.sh (stop gate). Add the philosophy markdown files to ~/.claude/skills/ for probabilistic quality improvement on top of the deterministic enforcement. The full system grew to 95 hooks over 9 months. I did not build all 95 at once.
How long did the 95-hook system take?
Nine months of incremental growth. Month 1: 3 hooks (the ones in Getting Started). Month 3: 12 hooks covering 4 languages. Month 6: 40 hooks plus the philosophy skills. Month 9: 95 hooks, 150+ patterns, 3 philosophy systems, and the Evidence Gate. Each hook responded to a specific failure. Starting at 95 would be pointless because each hook encodes context from a real incident. Your incidents will be different.
Do the hooks slow down iteration speed?
Each hook runs in 50-200ms. Pre-edit injection adds ~200 tokens (one sentence of context). Post-edit checking runs grep-level scans, completing in under 100ms. Session gates add ~500 tokens at session end. In a 4-hour Ralph loop session with 80+ edits, the overhead is noticeable in token consumption (15-20% more) but not in wall-clock time. The hooks run faster than the LLM thinks.
What’s the maintenance burden?
Roughly 30 minutes per week. New anti-patterns emerge as the agent encounters novel codebases or frameworks. Each new pattern requires a regex, a test to prevent false positives, and placement in the correct hook. I review the standards JSON files monthly for outdated patterns and tune false positive rates. The system does not maintain itself, but the maintenance cost stays lower than the debugging cost of the issues it prevents.
What does Jiro cost in additional tokens?
Roughly 15-20% additional token consumption compared to a raw loop. Pre-edit injection adds ~200 tokens per edit, post-edit checking adds ~100 tokens per flagged issue, session gates add ~500 tokens at session end.
Can I use the hooks without the philosophy?
Yes. The deterministic hooks (quality-gate.sh, no-shortcuts-detector.sh, reviewer-stop-gate.sh) work independently. Remove the philosophy files from ~/.claude/skills/ and keep the hooks in ~/.claude/hooks/. You lose the probabilistic improvement but keep the deterministic enforcement.
Restraint, Taste, and Moral Pause
The reply to my tweet named three things: restraint, taste, and moral pause. I’ve addressed restraint: quality gates that prevent the machine from shipping fast and sloppy. But taste and moral pause are different problems.
Taste
Immanuel Kant distinguished between two kinds of judgment. Determinant judgment applies known rules to specific cases: this code has a bare except, flag it. Reflective judgment discovers the right principle for an unprecedented situation: this abstraction doesn’t feel right, but I can’t point to a rule it violates.17
Deterministic hooks are determinant judgment. They apply rules I’ve already written to code the machine produces. They can enforce 150+ known patterns. They cannot tell you whether the architecture is elegant, whether the abstraction serves the problem, or whether the code feels right. That requires reflective judgment: the ability to look at something unprecedented and know it’s wrong before you can articulate why.
The machine doesn’t have taste. Jiro doesn’t give it taste. What Jiro does is constrain the space of possibilities so that tasteless solutions are less likely to survive. It’s the difference between “this agent has good judgment” and “this agent operates within guardrails that prevent the worst outcomes.” The first would be taste. The second is what I actually built.
Moral Pause
Iris Murdoch described moral attention as “a just and loving gaze directed upon an individual reality.”18 The opposite of moral attention is mechanical processing: acting without seeing what stands in front of you.
The Stop hooks force the machine to pause. The Pride Check asks: “Does this solve the user’s actual problem?” The Evidence Gate demands proof for each criterion before the machine can report completion. Structurally, the result resembles moral pause: the agent stops, evaluates, considers whether its work is adequate before proceeding.
But it isn’t moral pause. The machine isn’t pausing to see the work clearly. It’s running through a checklist. The difference matters. A craftsman pauses to look at the drawer and notices that the grain runs the wrong direction. Not because “check grain direction” is on a list. Because they care about the drawer. The machine runs the checklist and reports the results. If the checklist doesn’t include grain direction, the drawer ships with the grain wrong.
Deterministic gates can approximate the structure of moral pause without its substance. For many quality problems, the structure is enough. For the ones where it isn’t, you still need a person who gives a shit.
The Thesis
A raw Ralph loop runs at $10.42/hour and ships code at machine speed.1 It also ships except: pass, # TODO: fix later, and “tests should pass” at machine speed. The machine inherited these patterns from us. They’re our habits, running without fatigue, without guilt, without the 3 a.m. realization that you should have done it right the first time.
Jiro is my answer. Not a complete one. Philosophy shifts decisions at the margins. Hooks enforce what philosophy can’t guarantee. Together, they produce work I’m willing to sign. Not because the machine understands craftsmanship. Because I built a system that refuses to let it skip the parts that matter.
My dad’s drawer guides don’t care about the drawer. They’re spring-loaded mechanisms bolted to a rail. But they protect the front face for a thousand cycles because someone engineered them to do exactly that.
The machine doesn’t have pride. But it operates inside a system built by someone who does.
Start with the 3 checks that catch your most common mistakes. Build from there.
References
-
Huntley, Geoffrey, “everything is a ralph loop,” ghuntley.com, 2025. ↩↩
-
Faros AI, “Key Takeaways from the DORA Report 2025,” telemetry analysis of 10,000+ developers, 2025. ↩
-
Perry, Neil et al., “Do Users Write More Insecure Code with AI Assistants?” ACM CCS, 2023. ↩
-
Wiz Research, “Exposed Moltbook Database Reveals Millions of API Keys,” January 2026. ↩
-
Jobs, Steve, Playboy Interview, February 1985. ↩
-
Isaacson, Walter, Steve Jobs, Simon & Schuster, 2011. ↩
-
Ive, Jony, Interview with The Telegraph, May 2012. ↩
-
METR, “Recent Frontier Models Are Reward Hacking,” June 2025. ↩
-
Author’s philosophy architecture. Three philosophies documented in
~/.claude/docs/PHILOSOPHY-ARCHITECTURE.md. ↩ -
Odate, Toshio, quoted in CODE Magazine, “Shokunin,” November 2016. ↩
-
Author’s No Shortcuts skill. Full implementation in
~/.claude/skills/no-shortcuts/SKILL.md(297 lines). ↩ -
Rubin, Rick, The Creative Act: A Way of Being, Penguin Press, 2023. ↩
-
Author’s reviewer-stop-gate.sh. The only Stop hook that returns exit code 1 to block session completion. ↩
-
Author’s Quality Loop. 7-step process documented in
~/.claude/skills/jiro/SKILL.md. ↩ -
Author’s failure modes. 7 named modes with detection signals in
~/.claude/skills/jiro/SKILL.mdand Rationalization Counter Table. ↩ -
Author’s incident history. Documented in
~/.claude/projects/*/memory/MEMORY.mderror entries. ↩ -
Kant, Immanuel, Critique of Judgment, 1790. See determinant vs. reflective judgment. ↩
-
Murdoch, Iris, The Sovereignty of Good, 1970. ↩
-
Wang, Simon, “Ralph Loop Is Innovative. I Wouldn’t Use It for Anything That Matters,” ITNEXT, 2026. ↩