Writing

Essays

Things I have learned. Things I built, broke, and eventually figured out.

  1. Lazy by design: what MCP can learn from -h Jul 23, 2026 · 5 min A CLI costs zero tokens until the model asks for help, then reveals itself one -h at a time. MCP hands over every tool schema before the first question is asked. The protocol has five escape hatches (pagination, listChanged, meta-tools, deferred loading, code execution) and every one of them is a way of teaching MCP to behave like a shell. llmops
  2. A key wrapped in a key wrapped in a key Jul 21, 2026 · 9 min You type one passphrase, but ZFS native encryption juggles three kinds of key: a wrapping key derived from what you know, a random master key it guards, and a per-dataset data key derived from that. The indirection isn't bureaucracy — it's what makes changing a passphrase instant, inheritance sane, and 'send an encrypted backup to a machine you don't trust' a one-flag operation. Here's the whole hierarchy, the GCM authentication underneath, why copy-on-write lets ZFS reuse a per-block IV safely, and an honest account of what the encryption does not hide. cryptography · security · zfs
  3. Two disks down, still standing Jul 21, 2026 · 8 min The obvious way to survive two dead disks — add a second parity column — fails for a reason worth understanding: a second XOR is the same equation twice. RAIDZ2's fix is to compute its second parity in a finite field, GF(2⁸), weighting each disk by a distinct power of a generator. That turns two dependent equations into an always-solvable 2×2 system. Here's the field, the syndromes, the full reconstruction, and a playground where you can take out any two disks and watch the algebra put them back. math · storage · zfs
  4. One extra disk, one equation Jul 21, 2026 · 8 min RAIDZ1 survives a dead drive by keeping a single parity column that is nothing more exotic than the running XOR of the others. That one equation buys back any missing disk — but only when you already know which one lied, and that is the quiet reason ZFS pairs its parity with a checksum. Here's the algebra, the erasure-vs-error distinction that decides everything, and a live playground where you can kill a disk and watch it come back. math · storage · zfs
  5. The key server that never sees a key Jul 16, 2026 · 16 min LUKS encrypts your disk with field arithmetic in GF(2^128) and guards the key behind a memory-hard wall. Tang unlocks it over the network using a blinded Diffie-Hellman trick — McCallum-Relyea — so elegant that the server can hand back your key without ever learning it, or anything else. The whole stack, mathematics included. cryptography · linux · security
  6. How to agree on a secret in front of everyone Jul 15, 2026 · 13 min Diffie-Hellman key exchange lets two strangers build a shared secret while the whole world listens in. The trick is a one-way street in modular arithmetic: exponentiation is cheap, un-exponentiation is a wall. Here's the protocol, the group theory that makes it correct, the hardness assumptions that make it safe — and a live playground where you can run it, and try to break it. cryptography · math
  7. An MCP server is a protocol you can read Jul 7, 2026 · 10 min Build an MCP server in ~380 lines of Rust with no SDK: a wiretap whose only tool returns the raw JSON-RPC of its own session — handshake, negotiation, and the request that asked for it. llmops · rust · tutorial
  8. Snake, React-style, in your terminal Jun 29, 2026 · 14 min A complete snake game in one Rust file: signals for state, use_input for steering, an alternate screen for the arena, and a 200ms tick loop you own yourself. React patterns, zero JavaScript. rust · tui · tutorial
  9. What survived the port Jun 22, 2026 · 12 min Porting Ink from TypeScript to Rust: hooks and flexbox crossed over almost unchanged, the React reconciler didn't, and the most valuable artifact turned out to be the test suite — including the tests we refused to port. rust · tui
  10. A panic must not take the terminal with it Jun 15, 2026 · 12 min A panicking component in a TUI can leave your shell in raw mode with a hidden cursor. How inkrs catches component panics, surfaces them as last_error, and re-renders cleanly on the next tick. rust · tui
  11. The subtlest component in Ink Jun 8, 2026 · 12 min <Static> prints items exactly once, above a live region that repaints forever — the shape of every test runner and build log. The 'first Static is the accumulator' rule, and why append-only output inside a diffing renderer is harder than it looks. rust · tui
  12. Terminal rendering is a diff problem Jun 1, 2026 · 13 min Clear-and-reprint flickers; a real TUI repaints only what changed. Inside log-update: erase-line math, incremental line diffs, and a scroll-region trick that moves a whole band of the screen without redrawing it. rust · tui
  13. Forty years of history arrive on stdin May 25, 2026 · 12 min Arrow keys are three bytes, Esc is ambiguous by design, and Ctrl+I is indistinguishable from Tab. Parsing terminal keypresses in Rust, and how the kitty keyboard protocol finally cleans up the mess. rust · tui
  14. Your terminal executes strings May 18, 2026 · 13 min Every string you print is a little program: escape sequences can move the cursor, erase the screen, retitle the window. What sanitize-ansi strips before untrusted text hits the render grid — and why it's an allowlist, not a blocklist. rust · security · tui
  15. Wrapping text without breaking its colors May 11, 2026 · 11 min Naive line-wrapping cuts ANSI styles in half and bleeds color across your UI. How the wrap-text crate tokenizes styled text into SGR runs, wraps the visible characters, and keeps every line self-contained. rust · tui
  16. How wide is a string? May 4, 2026 · 10 min Rust gives you three ways to count a string — bytes, chars, graphemes — and a terminal UI needs a fourth. How the measure-text crate counts cells: CJK doubles, emoji lie, and ANSI escapes count for nothing. rust · tui
  17. Your primary key knows what time it is Sep 28, 2025 · 11 min UUIDv7 puts a 48-bit Unix timestamp in front of 74 random bits, and that one design decision fixes almost everything wrong with random UUIDs in a B-tree. Postgres 18 ships it natively, from the bit layout down to what it does to the rightmost leaf page. databases · postgres
  18. Adam: the optimizer that keeps its own running notes Nov 14, 2017 · 8 min Plain gradient descent takes the same timid step in every direction and stalls the moment the landscape turns into a canyon. Adam fixes this by remembering — it keeps a running average of where the gradient has been pointing, and a separate running average of how big it's been, then uses both to size each step per parameter. Here's the ladder from SGD to momentum to RMSProp to Adam, why those early steps need a bias correction, and a live playground where four optimizers race across the same landscape at once. machine learning · math
  19. ReLU: the bent line that taught networks to go deep Sep 19, 2017 · 9 min The rectified linear unit is the most consequential function in modern deep learning, and it is embarrassingly simple: keep the positives, zero out the negatives. That one kink is doing enormous work. It's the nonlinearity that stops a deep network from collapsing into a single matrix, the gradient that refuses to vanish where sigmoids choke, and — summed a few hundred times — a machine that can bend a straight line into any shape you like. Here's why max(0, x) beat the smooth curves, how it dies, what the variants fix, and a live playground where you stack ReLUs into any curve you want. machine learning · math
  20. Softmax: turning opinions into odds Jul 18, 2017 · 7 min A neural network's last layer speaks in logits — raw, unbounded scores with no sense of shame. Softmax is the diplomat that takes those numbers and hands back a genuine probability distribution: positive, summing to one, and steeper wherever the scores disagree most. Here's where the formula comes from, why it doesn't care about a constant shift (and why that quiet fact is what keeps it from overflowing), how a single temperature knob slides it between argmax and a coin flip, why the two-class case is just the logistic sigmoid wearing a hat, and why pairing it with cross-entropy makes the gradient collapse to something almost embarrassingly clean. machine learning · math
  21. Cross entropy: the price of believing the wrong distribution May 30, 2017 · 7 min Cross entropy is the loss that trains almost every classifier you've ever met, and it isn't an arbitrary formula bolted onto neural nets — it falls straight out of information theory. Start with entropy as expected surprise, add KL divergence as the extra cost of using the wrong code, and cross entropy is just the sum of the two. Here's the derivation, why it's the same thing as negative log-likelihood, why it pairs so cleanly with softmax that the gradient collapses to (prediction − target), and a live playground where you drag a predicted distribution around and watch the loss react. machine learning · math
  22. Logistic regression: bending a line until it becomes a probability Apr 25, 2017 · 8 min You can't answer a yes-or-no question with a straight line — a line runs off to infinity in both directions, and probabilities are stuck between 0 and 1. Logistic regression fixes this with one elegant move: keep the linear part, then squash it through a sigmoid. Here's why the log-odds turn out linear, how the Bernoulli likelihood collapses into cross-entropy, why there's no tidy closed form this time, and how a single clean gradient carries the whole thing downhill. machine learning · math · statistics
  23. Gradient descent: the art of rolling downhill Mar 28, 2017 · 8 min Least squares hands you the answer in one clean matrix solve — but only because the bowl is a perfect quadratic and small enough to invert. Take away either luxury and you need a method that finds the bottom without ever seeing the whole landscape: take a step in the steepest downhill direction, then look around and do it again. That's gradient descent. Here's the update rule, why the learning rate is the one knob that makes or breaks it, when convexity guarantees you arrive, and a live playground where you crank η until the whole thing flies apart. machine learning · math
  24. Linear regression: the honest workhorse Feb 21, 2017 · 9 min Fit a line, and least squares hands you numbers. Turn it into a model — with a claim about the world, error bars on every coefficient, and a theorem that says you can't do better without giving something up — and you have linear regression. Here's the model it actually asserts, why its estimator is provably the best of its kind, what each coefficient really means, and the four quiet assumptions holding the whole thing up. machine learning · math · statistics
  25. Least squares: the line that argues with every point Jan 17, 2017 · 8 min Draw a line through a cloud of points and you've already made a choice about what 'best' means. Least squares makes that choice precise — and it turns out to be two stories at once: a calculus problem you can solve by setting a gradient to zero, and a geometry problem where the answer is a shadow. Here's both derivations, why we square the errors in the first place, and a live playground where you drag the points and watch the line fight back. machine learning · math · statistics
  26. The directions that matter Dec 20, 2016 · 10 min Given a cloud of data in high dimensions, which few directions carry almost all of the story? Principal component analysis answers it by finding the axes along which the data varies most — and those axes turn out to be exactly the top eigenvectors of the covariance matrix, or equivalently the top singular vectors of the data. It's the spectral theorem, positive-definiteness, and the SVD all cashing out at once. Here's the derivation, why the leftover directions are the ones safe to drop, and a playground where you reshape a point cloud and watch its principal axes swing to follow. linear algebra · machine learning · math · statistics
  27. Every matrix in three acts Nov 8, 2016 · 10 min There's one factorization that works for every matrix — square or not, invertible or not — and it says something almost unreasonable: whatever a matrix does, it does it as a rotation, then a set of independent stretches, then another rotation. That's the singular value decomposition. Here's the geometry that turns a circle into an ellipse, why the singular values are the square roots of eigenvalues in disguise, the Eckart–Young theorem behind every low-rank approximation, and a playground where you watch the three acts play out. linear algebra · machine learning · math
  28. Positive definite: the shape of a bowl Sep 13, 2016 · 9 min Feed a symmetric matrix a vector from both sides and you get a single number — and the sign of that number, for every vector at once, decides whether a surface curves up like a bowl, down like a dome, or twists into a saddle. Positive-definite matrices are the bowls, and they're everywhere machine learning lives: covariance matrices, Hessians, the loss surfaces you roll downhill. Here's the quadratic form, the tests for definiteness, and a playground where you bend a matrix from bowl to saddle and back. linear algebra · machine learning · math · statistics
  29. Eigenvectors and the spectral theorem Jul 5, 2016 · 10 min Most vectors get knocked off course when a matrix hits them. A precious few don't — they only stretch or shrink, never turn. Those are the eigenvectors, and they're the closest thing a matrix has to a set of natural axes. Here's what Av = λv really means, how diagonalization makes powers of a matrix trivial, the spectral theorem that hands symmetric matrices a perfect orthonormal set of axes, and a playground where you watch power iteration home in on the dominant direction. linear algebra · machine learning · math
  30. The shadow of a vector May 3, 2016 · 9 min Ask where a vector's shadow falls on a wall and you've asked the deepest question in applied linear algebra. Projection is how you find the closest point in a subspace to a point outside it — and the leftover, the part you couldn't reach, always lands exactly perpendicular. Here's projection onto a line and onto a subspace, the projection matrix, Gram–Schmidt and QR, and a playground where you drag a vector and watch its shadow and its perpendicular residual move with it. linear algebra · machine learning · math
  31. The four fundamental subspaces Mar 8, 2016 · 9 min Every matrix quietly carves its two worlds — input space and output space — into four subspaces, and once you see them, the whole question of 'does this system have a solution?' becomes a matter of geometry. Here's the column space and null space, the rank–nullity theorem that ties their sizes together, why solvability means 'b lives in the column space', and a playground where you pick a target and watch it fall inside or outside the reachable set. linear algebra · machine learning · math
  32. A matrix is a verb: what a linear map does Jan 19, 2016 · 9 min A matrix isn't a grid of numbers you memorize rules for — it's a verb. It takes a vector and moves it. Its columns tell you exactly where the basis vectors land, and that alone pins down everything the matrix does to everything else. Here's the linear map hiding behind the notation, why matrix multiplication is really function composition, what the determinant measures, and a live playground where you drag the columns and watch the whole plane bend with them. linear algebra · machine learning · math