A TypeScript template, two Rust frameworks and one in Go. What each got wrong in order, and the two ideas that survived all of them.
A TypeScript template, two Rust frameworks and one in Go. What each got wrong in order, and the two ideas that survived all of them.
Checkpointed workflows, leader-elected cron and a dead letter queue, imported into the process you already deploy. What the model gives you and where it stops.
Rotation that requires a coordinated deploy happens once, at audit time. A grace window where both keys validate is what turns it into a background process.
A hash chain makes tampering detectable, which is the point. It also makes deletion impossible, which is a legal problem. Per-subject keys resolve it, with conditions.
Roles, attributes and relationships answer different questions and most systems need all three. Fixing the precedence rule up front is most of the design.
A manifest published by the service, consumed by the gateway. Why the configuration belongs with the service, and what putting discovery on the critical path costs.
Generating each database its own dialect instead of a portable subset. What that buys, what it costs, and the benchmark numbers with their caveats.
Every cross-tenant leak I have looked at came from one query missing one clause. Making the boundary structural means the mistake stops being available.
Four stores, one handler, no transaction. How I ended up with a reconciliation job nobody owned, and what a single transactional write path actually costs.
Job queues, webhook delivery, authorisation and billing as libraries you compile in rather than services you operate. The reasoning, and the three places it fails.
Minimalism does not remove decisions, it relocates them. Twenty-three things I decided before serving a single request, and the two the framework got wrong.
Training code is a fraction of a production machine learning system. The rest is data validation, serving, monitoring and the debt that accumulates when those are afterthoughts.