<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>topics on krtffl.dev</title><link>https://krtffl.dev/topics/</link><description>Recent content in topics on krtffl.dev</description><generator>Hugo</generator><language>en</language><copyright>© [krtffl](https://krtffl.dev)</copyright><atom:link href="https://krtffl.dev/topics/index.xml" rel="self" type="application/rss+xml"/><item><title>ai</title><link>https://krtffl.dev/topics/ai/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/ai/</guid><description>&lt;p&gt;i have written about this twice, nineteen months apart, and disagreed with
myself in between. both posts are here, in order, because the disagreement is
the interesting part.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-ai"&gt;what does this blog cover about ai?&lt;/h2&gt;
&lt;p&gt;in 2025 i called vibe coding the tiktok of programming — a dopamine trap, fast
feedback substituting for understanding. i still think the diagnosis was right.&lt;/p&gt;
&lt;p&gt;what i got wrong was the prescription. &amp;ldquo;don&amp;rsquo;t do it&amp;rdquo; is not a strategy when the
tools are genuinely useful, so the later post is about what replaced it: hooks,
blocked commands, and the fences that make an agent safe in a go codebase. the
uncomfortable part of writing it was noticing that my original fix was the same
mistake i keep writing about everywhere else — a check in the wrong layer,
trusting an input one hop too early.&lt;/p&gt;</description></item><item><title>go</title><link>https://krtffl.dev/topics/go/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/go/</guid><description>&lt;p&gt;go is what i write services in. it has been the day-job language at adidas and
now at motogp, and it is what most of my own products run on.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-go"&gt;what does this blog cover about go?&lt;/h2&gt;
&lt;p&gt;structure and the cost of structure, mostly. hexagonal architecture and whether
the ceremony pays for itself. sqlc and pgx instead of an orm, because sql that
fails at compile time beats sql that fails at 3am. shipping one self-contained
binary with the migrations and config embedded in it. authorization — owner
scoping, server-stamped ownership, the check that hides when you scatter it
across layers. and the honest counterweight to all of it: the boilerplate tax,
fourteen entities and an 890-line router.&lt;/p&gt;</description></item><item><title>infrastructure</title><link>https://krtffl.dev/topics/infrastructure/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/infrastructure/</guid><description>&lt;p&gt;one person, real production, no platform team. these posts are what that
actually costs.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-infrastructure"&gt;what does this blog cover about infrastructure?&lt;/h2&gt;
&lt;p&gt;the solo-founder stack first: what enterprise-grade actually means when it is
just you and your wallet, and which parts of the expensive playbook are worth
copying at one-person scale.&lt;/p&gt;
&lt;p&gt;then the failures, which are the useful part. &lt;code&gt;docker stack deploy&lt;/code&gt; silently
dropping a &lt;code&gt;command&lt;/code&gt; that &lt;code&gt;docker compose config&lt;/code&gt; renders perfectly — along with
three other swarm behaviours that fail without an error. and a production build
that ran 46 hugo releases behind local for months: every deploy green, every
config key i added silently ignored, and a fix that shipped broken for two days
because the key that fixed it did not exist in the version doing the building.&lt;/p&gt;</description></item><item><title>postgres</title><link>https://krtffl.dev/topics/postgres/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/postgres/</guid><description>&lt;p&gt;postgres is the default. every product i have built stores its state here, and
almost everything i have learned the hard way about concurrency, i learned from
it.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-postgres"&gt;what does this blog cover about postgres?&lt;/h2&gt;
&lt;p&gt;concurrency bugs first. the textbook lost update — a read-modify-write vote
handler that silently discarded 79% of every rating change under load, which is
the kind of number that only shows up if you go looking. read committed does not
mean what people assume it means, and that post is the proof.&lt;/p&gt;</description></item><item><title>rust</title><link>https://krtffl.dev/topics/rust/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/rust/</guid><description>&lt;p&gt;rust is what i write tools in. not services — tools: the things that parse
gigabytes, run once, and have to be right and fast at the same time.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-rust"&gt;what does this blog cover about rust?&lt;/h2&gt;
&lt;p&gt;algorithms implemented from papers, mostly, and the parts the paper leaves out.
the drain algorithm for streaming log-template extraction. welford&amp;rsquo;s online
variance, so a rolling z-score never has to store the samples. a query dsl built
by hand — tokenizer, recursive-descent parser, tree-walking evaluator — and when
not to reach for a parser generator. zero-copy parsing straight out of an mmap,
and the single invalid byte that turns it back into a heap copy.&lt;/p&gt;</description></item><item><title>security</title><link>https://krtffl.dev/topics/security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/security/</guid><description>&lt;p&gt;every post here is about a hole i shipped and then found, which is the only kind
of security writing i am qualified to do.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-security"&gt;what does this blog cover about security?&lt;/h2&gt;
&lt;p&gt;authorization, almost entirely — the boring kind that leaks data rather than the
exciting kind that makes the news.&lt;/p&gt;
&lt;p&gt;a rate limiter that trusted &lt;code&gt;X-Forwarded-For&lt;/code&gt;, with two measured bypasses: a
rotating forwarded header and a missing cookie, plus the trusted-proxy fix. a
create endpoint that read &lt;code&gt;OwnerID&lt;/code&gt; off the request body, and why a field you
validate is still a field you trusted. owner-scoped rbac, and the authorization
inconsistency that hides the moment you scatter the check across layers.
multi-tenant isolation treated as a security boundary rather than a query
filter, with the privilege-escalation hole that was sitting in the plugin
defaults. and public endpoints that each allocate eight megabytes with no cap
between them, which is a denial-of-service you host yourself.&lt;/p&gt;</description></item><item><title>statistics</title><link>https://krtffl.dev/topics/statistics/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/statistics/</guid><description>&lt;p&gt;i did a double degree in physics and chemistry before i wrote software for a
living, which mostly means i know how easy it is to compute a number that is
wrong in a way nothing warns you about.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-statistics"&gt;what does this blog cover about statistics?&lt;/h2&gt;
&lt;p&gt;numerical correctness, and the specific ways it fails quietly.&lt;/p&gt;
&lt;p&gt;welford&amp;rsquo;s algorithm, because the textbook variance formula — sum of squares
minus the square of the sum — loses catastrophic precision on large streams, and
because storing the samples to avoid that is not an option when the stream is
gigabytes of logs. ordinary least squares implemented by hand, and the
collinearity trap: a singular matrix that produced confident nonsense until a
guard turned it into an honest &lt;code&gt;None&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>testing</title><link>https://krtffl.dev/topics/testing/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://krtffl.dev/topics/testing/</guid><description>&lt;p&gt;this is the topic i have most publicly changed my mind about, so it is the one
worth reading in order rather than by relevance.&lt;/p&gt;
&lt;h2 id="what-does-this-blog-cover-about-testing"&gt;what does this blog cover about testing?&lt;/h2&gt;
&lt;p&gt;testcontainers, in three parts: real postgres in the test suite instead of a
mock, what it costs in ci minutes, and the reality check after living with it.&lt;/p&gt;
&lt;p&gt;and then the retraction. a year ago i argued that testing was a waste of time for
a solo developer shipping fast. then a lost-update race
&lt;a href="https://krtffl.dev/posts/elo-lost-update-postgres/"&gt;silently ate 79% of every vote&lt;/a&gt;

in a live product — a bug no amount of manual clicking would ever have surfaced,
because it only appears under concurrency. so i wrote the retraction, with the
seven things i shipped in between and what each of them actually needed.&lt;/p&gt;</description></item></channel></rss>