Things I Learned
Short, dated notes on things I’ve learned. Longer write-ups live in Writing.
How the Claude Code team does code review
How the Claude Code team does code review. Claude writes ~90% of Claude Code, so nobody reads every diff. They swapped “did a human read it?” for “which check, automated or human, should catch what could go wrong here?”, and optimise for the least human time per change, with revert and incident rates as the guardrail.
- The bit I missed on first read: review noise costs more when the author is an agent. A person waves off a nit in seconds; an agent fixes every one, which is a new commit and another full review. One PR ran 50+ rounds overnight, and ~59% of later findings were on code already there at round one. Fix: cap at three rounds, re-review only the new diff, flag the class of bug, never repeat a finding.
- The bot posts findings, never approvals. Human approvals (zero, one or two) are set by the change’s risk, not by who wrote it. Whoever prompted the agent counts as a reviewer, and an approval covers one commit, so an agent’s next push dismisses it.
- Their reviewer’s eval is their own past incidents and reverts, run daily. Noise is measured by what authors did with each comment: fixed it, said it was wrong, intentional, or not worth it.
- Versus Ankit Jain’s review layers I noted in April: this is the production version, with no spec-review layer and fast rollback under everything.
- Read the numbers carefully: the share of PRs reverted fell 40% while PR volume doubled, so the count of reverts still rose (~1.2x). Also: the authors sell the reviewer.
- Where I push back: “nobody needs a full mental model, ask Claude for an explainer of the slice you’re changing.” An explainer recovers what the code does, not why it was built that way, which is the comprehension debt Addy Osmani (a co-author here) wrote about. People should spend review on whether to ship it and on direction, not line-level correctness.
- How I read it: had Claude explain it against my notes, then quiz me. The question I got wrong taught me the most.
'AI' is Not a Tool
Rich Hickey’s "‘AI’ is Not a Tool" vs Huahai Yang’s “AI Is a Tool. Using It Well Takes Skill.”. Hickey: a tool is something you wield, and wielding is where expertise comes from, so an LLM is automation you abdicate work to. Yang: a compiler also works unattended and is still a tool; the line is skilled use vs delegating without oversight. Arguing over the label is a dead end. What matters is which skill survives.
- Hickey’s best line: you are “only a software update from everything you’ve ’learned’ being rendered obsolete.” Model quirks and prompt recipes expire. Verification, choosing context and domain judgment carry over to the next model.
- Bainbridge’s Ironies of Automation said it in 1983: automate the work and the operator is left monitoring, which needs the skill they stopped practicing. My rule: do the work, then ask the model. Don’t ask the model instead.
- Best reply to “LLMs are slot machines” in the HN thread: a Las Vegas algorithm is random but always correct; only the runtime varies. Randomness plus a verifier gets you accuracy. Without the verifier you’re just pulling the lever.
Rampart
Small on-device models are getting good enough to sit in front of the big ones. Rampart from the National Design Studio redacts PII in the browser before a prompt reaches any LLM: regexes with checksum or structural checks for cards (Luhn), SSNs, emails, URLs and IPs, plus a fine-tuned MiniLM for names, phones, account numbers, government IDs and street addresses.
- 14.7 MB Q4 ONNX (~15 MB with tokenizer), 98.4% private-term recall across seven Latin-script languages. p50 is 3.9 ms on WebGPU but 12.6 ms on the default WASM backend. OpenAI’s Privacy Filter is ~2.8 GB; Presidio scores 65% on the same test set.
guard.protect()swaps PII for placeholders like[GIVEN_NAME_1], andguard.reveal()fills them back into the reply. The LLM never sees the name; the user still does.- Default-deny: every detected label is redacted except city, state and ZIP, so the assistant keeps coarse location without the street line.
- Know the gaps: names in non-Latin scripts recall ~14% (Hindi 6%, Arabic 5%), and it scores 86.4% on a hostile-input suite. The repo calls it harm reduction, not perfect protection.
- Same size class, different job: Cactus Whistle is 16.9 MB speech-to-text in seven languages, 11 ms to first token on an M4 Pro CPU (Whisper base: 145 MB, 73 ms). It loads into the same engine as Needle 3, their tool-calling model, so one call takes audio in and returns
set_lights(room="kitchen", on=false). Voice commands for home automation with no cloud round trip. - The pattern: a tiny specialist at the edge does one narrow job (redact, transcribe, route), and the big model only sees what it needs. Both sets of benchmarks are vendor-reported.
Sebastian Raschka's history of text classifiers
Sebastian Raschka’s history of text classifiers puts numbers on why Jev feels new. On IMDb, bag-of-words + logistic regression gets 89.9%, a fine-tuned ModernBERT about 95%, and Jev 96.5% zero-shot for $0.65 across 25k reviews. Under the hood it is likely still a pretrained transformer with a one-number head that scores each answer option. The hard part is broad training data and calibrated probabilities. What changes is the cost of starting: no labelling, training or hosting per task. Specialists still win on huge volume, the last point of accuracy, or data that can’t leave your network. Within a month OpenAI and Microsoft shipped the same yes/no, choice and score contract.
Microsoft eXecution Container (MXC)
Microsoft eXecution Container (MXC) is an embeddable SDK for running untrusted commands under OS-enforced policies, not a hosted sandbox service.
- Defaults: Seatbelt on macOS, Bubblewrap on Linux, ProcessContainer on Windows. SDKs for Node, Rust, and .NET.
- Restricts filesystem and network access. macOS hostname allowlists need a caller-managed proxy; not every backend is a VM.
- Useful boundary: sandbox the command where it executes, not just the agent’s tool-composition script. Isolation limits damage; it does not make generated output trustworthy.
Pi Pocket's subagent implementation
Pi Pocket’s subagent implementation gives each worker a retained conversation and uses durable tasks to deliver messages and report answers. Request IDs and recorded answer IDs prevent duplicate delivery and reporting after restart. The idea worth stealing: make the handoff durable, not just the worker.
Armin Ronacher's subagent extension
Armin Ronacher’s subagent extension runs one observable Pi child at a time in tmux. The parent waits for the result, while I can attach to inspect or intervene. Worth preserving when adding hierarchy: synchronous coordination must not mean invisible execution.
Wispr Flow
Back on Wispr Flow after six months on local speech-to-text (FluidVoice with Parakeet, plus Whisper). Local transcription is fine. The cleanup is what’s missing: fixing misheard jargon ate the time dictation saved. Flow’s correction pass, OS-level integration and phone keyboard win. It matters more now because models follow high-level intent well: I speak the intent plus constraints in one go and let the LLM structure it. Whisper mode works even when you speak softly. Want to try it? My referral link gets you a free month of Pro, and I get one once you’ve dictated 2,000 words.
Pi Durable
Pi Durable is Earendil’s experimental agent harness, shipped alongside Pi 1.0. TannerMidd/pi-pocket is a mobile-first, multiplayer web app for Pi built on it.
- Every model call and tool call is a task that checkpoints to storage (SQLite, JSONL, or memory) before moving on. Kill the process and a new one opens the same file and resumes.
- Recovery is per step: a cut-off model request is resent with the partial answer kept and marked aborted. A cut-off tool call reruns only if it is replay-safe; otherwise the model is told it was interrupted.
- A
requestIdmakes a submission exactly-once, so a client retrying after a crash gets the original back. - Forks see the parent transcript up to the fork point without copying it.
- ~15k lines total, small enough for an agent to read end to end.
- pi-pocket: restart the server mid-run and the work continues. Several people can watch, steer, or queue messages on the same session.
npm start -- --access tailscalebinds only to the tailnet address, so my phone gets it with no tunnel.- The shift: the session lives in a SQLite file, not a terminal process, so the phone is just another client. Could replace my Moshi + tmux setup.
- Caveat: anyone who can steer runs shell commands as you.