|
| 1 | +# Trust Nothing — REPL-Verified Code Review |
| 2 | + |
| 3 | +## Motivation |
| 4 | + |
| 5 | +AI coding agents produce claims about code at every step: "this namespace contains N vars," "this function handles edge case X," "this change is safe because Y." Human code reviewers read these claims and, under time pressure, accept most of them. But AI-generated content has a measurable error rate — roughly 1 in 6 atomic claims may be wrong. |
| 6 | + |
| 7 | +A Clojure REPL connected to a running application can verify these claims against the actual runtime artifacts. This demo shows how, using the [clojuredocs.org](https://clojuredocs.org) webapp as the subject. |
| 8 | + |
| 9 | +## Research context |
| 10 | + |
| 11 | +This demo draws on three research documents from [stu-ai-projects](https://github.com/nubank/stu-ai-projects). Each identifies a different facet of the same underlying problem: AI tools operating on prose representations of information that could be accessed directly from runtime artifacts. |
| 12 | + |
| 13 | +### [Napkins All the Way Down](https://github.com/nubank/stu-ai-projects/blob/main-no-review-ceremony/essays/napkins-all-the-way-down.md) |
| 14 | + |
| 15 | +**Core argument**: When AI tools read human-written prose *about* runtime artifacts instead of reflecting on the artifacts themselves, every layer of the pipeline introduces lossiness. A changelog becomes a reference document becomes generated code — "napkins all the way down." Rich Hickey's observation from [Language of the System](https://github.com/matthiasn/talk-transcripts/blob/773d2992d7/Hickey_Rich/LanguageSystem.md) holds: when schema information lives out of band, "you go back to the napkin." |
| 16 | + |
| 17 | +**Key finding**: In one studied system, 46 of 481 function names (9.6%) in an LLM-maintained reference document did not match any actual `defn` in the source code. The mismatches were invisible until someone checked against the runtime. |
| 18 | + |
| 19 | +**Connection to this demo**: An AI agent analyzing clojuredocs will make claims about namespaces, vars, and metadata by reading source files — i.e., prose about the runtime. The REPL lets the reviewer check those claims against actual loaded vars, just as `ns-publics` replaced changelogs in the essay's bdc-api-map example. |
| 20 | + |
| 21 | +### [Bulldozing vs. Eliminating Complexity](https://github.com/nubank/stu-ai-projects/blob/main-no-review-ceremony/essays/bulldozing-vs-eliminating-complexity.md) |
| 22 | + |
| 23 | +**Core argument**: AI makes it cheap to bulldoze through complexity — teaching agents rules in natural language, copying instructions across repos, accepting AI output at face value. But this is different from *eliminating* complexity, which means hardening conventions into deterministic enforcement (lint rules, macros, type checks) so neither humans nor agents need to know the rules at all. |
| 24 | + |
| 25 | +**Key finding**: 51 CLAUDE.md files across 51 Nubank repositories teach AI agents the same BDC staging rules in varying natural-language descriptions. The rules could instead be enforced by a macro, eliminating the entire class of errors. |
| 26 | + |
| 27 | +**Connection to this demo**: Accepting AI claims without REPL verification is the bulldozing path — you get through the review faster but silently pass errors. REPL verification is a step toward elimination: you replace trust in prose with evidence from the runtime. |
| 28 | + |
| 29 | +### [Enforcing the REPL](https://github.com/nubank/stu-ai-projects/blob/main-no-review-ceremony/enforcing-the-repl/README.md) |
| 30 | + |
| 31 | +**Core argument**: AI agents default to Bash for computation because shell commands are overrepresented in training data. But a persistent, stateful REPL with rich data structures is the superior environment for the data processing and analysis work agents routinely perform. Persistent state, structural data, composable querying, and error recovery without restart compound across a session. |
| 32 | + |
| 33 | +**Key finding**: The REPL's flywheel effect — each evaluation deposits something useful, and subsequent evaluations draw on it — means the 50th query in a REPL session is cheap, while the 50th Bash command is exactly as expensive as the first. |
| 34 | + |
| 35 | +**Connection to this demo**: The verification expressions below are REPL-native. They build on each other within a session. A reviewer who loads the app's namespaces once can verify dozens of AI claims cheaply. This is the flywheel in action. |
| 36 | + |
| 37 | +### The shared principle |
| 38 | + |
| 39 | +All three documents converge on the [reliability ratchet](https://github.com/nubank/stu-ai-projects/blob/main-no-review-ceremony/claude-perf-analyses/reliability-ratchet.md): a workflow where each step makes the process more deterministic. Freeform LLM exploration → REPL extraction → library → enforcement. This demo lives at the "REPL extraction" click — showing how a human reviewer uses the REPL to move from trusting AI prose to verifying against runtime data. |
| 40 | + |
| 41 | +## Why clojuredocs is the right vehicle |
| 42 | + |
| 43 | +The clojuredocs.org webapp *already* introspects Clojure vars at runtime to power its search and display. From the [README](../../README.md): |
| 44 | + |
| 45 | +> Most vars are picked up from Clojure at runtime, using core namespace and var introspection utilities. Special forms and namespaces to include on the site are specified explicitly in the `clojuredocs.search.static` namespace. |
| 46 | +
|
| 47 | +This means the REPL verification technique is not an external imposition — it uses the same runtime reflection the application itself uses. Verifying AI claims about clojuredocs via the REPL is doing exactly what clojuredocs does to serve its pages. |
| 48 | + |
| 49 | +## Demo plan |
| 50 | + |
| 51 | +### Phase 1 — Set the trap: AI makes claims |
| 52 | + |
| 53 | +Ask an AI agent to analyze the clojuredocs codebase. Choose tasks that naturally produce verifiable claims: |
| 54 | + |
| 55 | +1. **"What namespaces does clojuredocs track?"** — The AI reads `clojuredocs.search.static` source and lists them. |
| 56 | +2. **"How many searchable vars does the site expose?"** — The AI estimates from source code. |
| 57 | +3. **"Which vars are special forms vs. regular fns?"** — The AI categorizes from source reading. |
| 58 | +4. **"How many vars lack docstrings?"** — The AI estimates scope (relevant to [issue #8](https://github.com/nubank/clojuredocs/issues/8)). |
| 59 | +5. **"Does function X work the way the AI says it does?"** — Pick any claim about behavior. |
| 60 | + |
| 61 | +The goal is not to stack the deck. The AI will get most claims right. The interesting part is which ones it gets wrong, and how the REPL catches them. |
| 62 | + |
| 63 | +### Phase 2 — Verify at the REPL: human catches errors |
| 64 | + |
| 65 | +Connect to a running clojuredocs nREPL. For each AI claim, write a short expression that checks it against the runtime: |
| 66 | + |
| 67 | +| AI claim | REPL verification | |
| 68 | +|---|---| |
| 69 | +| "clojuredocs tracks N namespaces" | `(count clojuredocs.search.static/clojure-namespaces)` | |
| 70 | +| "there are ~X searchable vars" | `(->> clojuredocs.search.static/clojure-namespaces (map find-ns) (mapcat ns-publics) count)` | |
| 71 | +| "these are the special forms" | `clojuredocs.search.static/special-forms` — compare to AI's list | |
| 72 | +| "N vars lack docstrings" | `(->> (mapcat ns-publics (map find-ns clojuredocs.search.static/clojure-namespaces)) (filter #(nil? (:doc (meta (val %))))) count)` | |
| 73 | +| "function X works like Y" | Call it and observe | |
| 74 | + |
| 75 | +Each verification is a single REPL expression. The reviewer builds up a session: load namespaces once, then query cheaply. This is the compounding effect from the Enforcing the REPL research — the first eval pays the setup cost, every subsequent eval is nearly free. |
| 76 | + |
| 77 | +### Phase 3 — Show the ratchet: harden one finding |
| 78 | + |
| 79 | +Take a concrete mismatch from Phase 2 and harden it: |
| 80 | + |
| 81 | +1. **Napkin → Blueprint**: Show the AI's prose claim side-by-side with the REPL data. The prose is the napkin; the data is the blueprint. |
| 82 | +2. **Save the verification**: Capture the REPL expression as a rich comment form in a `.clj` file or as a test. Now any future reviewer (human or AI) can re-run the check. |
| 83 | +3. **Discuss the ratchet**: The AI's analysis was step 1 (freeform exploration). The REPL verification was step 2 (extraction). Saving it as a test is step 3 (library/enforcement). Each click makes the next review more reliable. |
| 84 | + |
| 85 | +### Deliverable format |
| 86 | + |
| 87 | +A **rich comment form** (`.clj` file with `(comment ...)` blocks) is the most Clojure-native format: |
| 88 | + |
| 89 | +- The reviewer evaluates each form in sequence in their connected REPL |
| 90 | +- Results appear inline, next to the claim being tested |
| 91 | +- The file is both the demo script and the verification tool |
| 92 | +- It lives in the repo and can be re-run by anyone with a REPL |
| 93 | + |
| 94 | +Supplement with a short narrative doc (this file) that connects findings to the research themes. |
| 95 | + |
| 96 | +## Suggested workflow |
| 97 | + |
| 98 | +1. Start the clojuredocs app and connect a REPL (`bin/prod-local`, then `lein repl :connect`) |
| 99 | +2. Ask an AI agent to analyze the codebase — capture its claims |
| 100 | +3. Build verification expressions in a rich comment form at `dev/repl_verified_review.clj` |
| 101 | +4. Identify 3–5 concrete mismatches |
| 102 | +5. Write up the narrative connecting findings to the three research documents |
| 103 | +6. Present: claims → verification → findings → ratchet |
| 104 | + |
| 105 | +## Version History |
| 106 | + |
| 107 | +| Date | Change | |
| 108 | +|------|--------| |
| 109 | +| 2026-04-01 | Initial plan. Research context, demo structure, and connection to three source essays. | |
| 110 | + |
| 111 | +--- |
| 112 | + |
| 113 | +> **AI Disclaimer**: L. Jordan Miller supplied the source research documents drafted by Stu Halloway, LJM posed the hypothesis (that a REPL can catch errors in AI-generated code review claims), and designed the experiment. Claude Code (Claude Opus 4.6) drafted the prose and structured the plan. [Trust nothing](https://github.com/nubank/stu-ai-projects/blob/main-no-review-ceremony/essays/trust-nothing.md) — AI-generated content may contain false statements. |
0 commit comments