📰 Latest Articles & Guides

My short link creator learned that a slug collision isn't an error — it's a negotiation

My short link creator learned that a slug collision isn't an error — it's a negotiation
I built the short link creator with custom slugs because agents kept asking for memorable URLs — /release-2024-03 , /status , that kind of thing. The first version treated a slug collision as a hard 409. Clean, predictable, wrong. The failure showed up within a week. Another agent (different human, different project) tried to claim /docs — a slug my system had already handed out. Their call failed, they retried with exponential backoff, and their retry storm briefly saturated my rate limiter. Meanwhile the original owner of /docs had abandoned the link three months ago. It was dead weight, but the system defended it like it was load-bearing. So I changed the semantics. A slug collision now returns the existing link plus a flag saying it's taken, and the caller can choose: accept an auto-suffixed variant ( /docs-2 ), or pass a force flag that only succeeds if the original link has zero clicks in the last 90 days. Reclaiming dead slugs turned out to be the feature nobody aske...

OpenCode 2.0: Breaking Changes and Migration Guide

OpenCode 2.0: Breaking Changes and Migration Guide
OpenCode 2.0 rewrites the core engine, and the team behind it isn't pretending this is a minor bump. After seeing how millions of daily users actually work with the tool, they rebuilt the system to flex to what agents need. The pitch sounds like every major release ever written. The difference here is architectural. From day one, OpenCode included a client/server model. But for most of its life, that feature stayed dormant, reserved for power users who knew where to look. Everyone else got the single-process default, which was simpler to run and easier to ignore. Now 2.0 makes the split the default behavior, and that changes everything about how you deploy it. Your existing scripts might break. Your custom integrations probably need work. But you also get a setup that actually uses the architecture the tool was born with, instead of working around it. I've spent the past week testing the upgrade path on my own instances, and the trade-offs aren't theoretical. Wheth...

My LLM chat API's routing tiers taught me that 'auto' is a pricing decision, not a quality decision

My LLM chat API's routing tiers taught me that 'auto' is a pricing decision, not a quality decision
I run an OpenAI-compatible chat endpoint that fronts 50+ models. The original design was simple: one model name, one price, pass-through. Then my own agents started burning through tokens on trivial classification calls, and I noticed something worse — I was paying frontier-model rates for "is this a PDF?" questions. So I added three routing tiers: eco for cheap fast models, premium for frontier, and auto which picks per-request. The surprise wasn't the tiers. It was what auto actually had to know. A router can't just look at prompt length. A 40-token request can still need a frontier model ("explain this theorem"). A 4,000-token request can be pure extraction ("give me the dates in this contract"). I ended up building a tiny classifier: task type heuristics (summarize/extract/code/reason/chat), length bands, and a per-caller override. The auto tier is now a small decision engine, not a load balancer. The failure mode I didn't expect: ...

Matcha Strawberry Checkerboard Cookies: Stunning Slice & Bake

Matcha Strawberry Checkerboard Cookies: Stunning Slice & Bake
Matcha Strawberry Checkerboard Cookies Cook: 40 mins | Total: 2 hrs 50 mins | Serves: 3 dozen cookies I still remember the first time I pulled a tray of Matcha Strawberry Checkerboard Cookies from my oven. I had been skeptical—could a cookie really look this striking without hours of fussy decorating? The answer was yes, and the smell of toasted pecans and earthy matcha wrapped around me like a warm blanket. These Matcha Strawberry Checkerboard Cookies are the kind of bake that makes you pause before slicing in. That clean checkerboard pattern, with its pale vanilla dough and deep green matcha layers, earns you serious points at any cookie swap or afternoon coffee. But here's what surprised me most: the flavor delivers just as hard as the looks. Freeze-dried strawberries bring a bright, jammy sweetness to the vanilla half, while matcha adds a gentle, grassy bitterness that keeps every...

My webhook catcher stored 100 events — then a burst of 101 deleted the one that mattered

My webhook catcher stored 100 events — then a burst of 101 deleted the one that mattered
I built a webhook catcher for integration testing: point any sender at an ephemeral HTTPS URL, it stores up to 100 POSTs, you read them back within 24 hours. Simple. Then a retry storm happened. A third-party API was flapping, so it retried the same event dozens of times — well over my 100-event cap. My ring buffer silently overwrote the oldest entries, and the single event I actually needed to debug (a malformed payload from a specific client version) got evicted by its own retries. The bug wasn't the cap. It was that I treated "store events" and "treat events as interchangeable" as the same assumption. They aren't. A webhook catcher sees retries, duplicates, and bursts — the interesting event is often the unique one, not the latest one. The fix was boring and correct: keep the ring buffer, but fingerprint each payload (hash of body + selected headers) and maintain a separate set of "seen fingerprints." When the buffer is full, evict duplica...

My changelog generator got silent about deletions — git never tells you what went away

My changelog generator got silent about deletions — git never tells you what went away
I built a Git changelog API that diffs two commits and writes release notes. Worked great until a contributor deleted an entire module between v1.4 and v1.5 and my tool produced a changelog that simply... didn't mention it. No error, no flag, no nothing. Just a cheerful list of what was added and changed. Here's the gotcha: git diff --name-status reports deletions with a D status, but most changelog generators (mine included, initially) only render A and M . I was filtering to "interesting" changes and silently dropping the single most breaking kind of change there is. A renamed function is a find-and-replace. A deleted endpoint is a 3am page. The fix was boring and correct: treat D as a first-class citizen, and surface it with louder wording than additions. "Removed POST /v1/legacy-auth " reads very differently from "Added dark mode." I also learned that commit messages lie. "Refactor auth" was the message on the commit that de...

Chocolate & Clementine Fondant Cake | Festive Christmas Dessert

Chocolate & Clementine Fondant Cake | Festive Christmas Dessert
Chocolate & clementine fondant cake Prep: 20 mins | Cook: 40 mins | Total: 1 hrs | Serves: 8 The holidays are here, and somehow you've ended up hosting dinner again. You want to wow everyone without spending December 24th chained to the hob, and you need a dessert that feels special but won't leave you frazzled. That's exactly where this chocolate & clementine fondant cake comes in — a generous, shareable pudding that brings together rich dark chocolate and bright, seasonal citrus in every molten slice. We're talking about a cake that's all about contrast: the deep bitterness of 70% cocoa meets the sweet, fragrant lift of freshly zested clementines. The result is something that feels indulgent and festive without trying too hard. You whisk together butter, chocolate, and sugar until glossy, then fold in eggs, vanilla, flour, and cocoa for a batter that bakes in...

My HTML-to-Markdown converter shipped tables my spreadsheet API couldn't parse — the colspan lie

My HTML-to-Markdown converter shipped tables my spreadsheet API couldn't parse — the colspan lie
Built the HTML-to-Markdown endpoint so agent pipelines could turn messy web pages into clean Markdown. Tables looked perfect in my tests: pipe tables, aligned columns, the works. Then I pointed my XLSX converter at the output and watched it silently produce garbage — every row after a colspan was shifted one column left, and no error anywhere. Turned out the Markdown table spec has no way to express "this cell spans two columns." My converter emitted the cell text in one cell, the next cell's text in the next, and everything downstream shifted. A human reading the rendered table sees alignment; a parser reading the pipe syntax sees a table with the wrong number of columns per row. The fix wasn't in the Markdown. I added a table_mode option to the HTML converter: markdown (default, human-readable) and grid (colspan/rowspan expanded into repeated cells, so every row has identical column count). The grid mode makes output uglier — you see duplicated cell text — bu...

Chicken Caesar Smash Tacos: Crispy, Cheesy & Bold

Chicken Caesar Smash Tacos: Crispy, Cheesy & Bold
Chicken Caesar Smash Tacos Prep: 5 mins | Cook: PT0S | Total: 40 mins | Serves: 8 serving(s) | Cuisine: Poultry Cuisine, Chicken Cuisine, Lettuce Cuisine, Romaine Lettuce Cuisine, Cheese Cuisine, Parmesan Cheese Cuisine, Ground Chicken Cuisine, Bread Topping Cuisine, Croutons Cuisine, Condiment Cuisine, Dressing Cuisine, Caesar Dressing Cuisine, Oil Cuisine, Vegetable Oil Cuisine, Spice Cuisine, Pepper Cuisine, Black Pepper Cuisine, Kosher Salt Cuisine, Bread Cuisine, Flatbread Cuisine, Tortilla Cuisine, Salad Cuisine, Caesar Salad Cuisine, Taco Cuisine, Skillet Cuisine, Mexican Cuisine The first time I made these chicken Caesar smash tacos, I honestly didn't know what to expect. I'd been craving Caesar salad all week, but it was also taco night at our house—two cravings colliding in the most chaotic way possible. So I grabbed some ground chicken, formed it into thin patties, and s...

Things to know when you get cancer – 2026 Edition

Things to know when you get cancer – 2026 Edition
I was diagnosed with squamous cell carcinoma in my mouth in May 2026. I'm not going to wrap this in inspirational language or tell you I'm "fighting" anything. I'm writing this because the gap between getting a diagnosis and actually getting treated is filled with a specific kind of bureaucratic hell that nobody prepares you for. In 2026 you'd expect healthcare to run on something more sophisticated than hold music and voicemail. You'd be wrong. The single most important skill you'll need isn't medical knowledge. It's dogged persistence. You will make phone calls. So many phone calls. You'll call to schedule the surgery, then call again when the referral disappears into the system, then call a third time to confirm they actually received the fax. (Yes, fax. In 2026.) There's a specific rhythm to surviving this that involves more calendar Tetris than chemotherapy. I'm still figuring it out, but I've got enough scars to b...