<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>koray.dev</title><description>Koray Güler builds product at koative, an independent software studio in İstanbul. Notes on typed edges, small dependency lists and calm software.</description><link>https://koray.dev/</link><item><title>Your LLM can&apos;t hallucinate a number it was never given</title><link>https://koray.dev/posts/llm-cannot-hallucinate-what-you-never-sent/</link><guid isPermaLink="true">https://koray.dev/posts/llm-cannot-hallucinate-what-you-never-sent/</guid><description>Anti-hallucination gets written as a prompt rule. It belongs in the code that builds the prompt, and the sharpest version of it is one line long.</description><pubDate>Sat, 18 Jul 2026 06:00:00 GMT</pubDate></item><item><title>Three bugs, one root cause: the label was not the identity</title><link>https://koray.dev/posts/the-label-was-not-the-identity/</link><guid isPermaLink="true">https://koray.dev/posts/the-label-was-not-the-identity/</guid><description>A rendering layer derives a human label from a machine identity. Both are strings. The type checker has nothing to say and the money path does.</description><pubDate>Sat, 04 Jul 2026 06:00:00 GMT</pubDate></item><item><title>Cache the prompt, not the inputs</title><link>https://koray.dev/posts/cache-the-prompt-not-the-inputs/</link><guid isPermaLink="true">https://koray.dev/posts/cache-the-prompt-not-the-inputs/</guid><description>The key listed the inputs someone believed mattered. The prompt had grown three fields since, and nothing in the system could have noticed.</description><pubDate>Sat, 27 Jun 2026 06:00:00 GMT</pubDate></item><item><title>The endpoint that succeeded at doing nothing</title><link>https://koray.dev/posts/the-endpoint-that-succeeded-at-doing-nothing/</link><guid isPermaLink="true">https://koray.dev/posts/the-endpoint-that-succeeded-at-doing-nothing/</guid><description>Correct status code, clean logs, zero exceptions, wrong data. What happens to the promise you deliberately didn&apos;t await.</description><pubDate>Fri, 05 Jun 2026 06:00:00 GMT</pubDate></item><item><title>I put a signing key in the browser on purpose</title><link>https://koray.dev/posts/a-signing-key-in-the-browser/</link><guid isPermaLink="true">https://koray.dev/posts/a-signing-key-in-the-browser/</guid><description>What that buys, split by what the attacker can already do, and why the property that actually protects the user is not in my code at all.</description><pubDate>Sat, 30 May 2026 06:00:00 GMT</pubDate></item><item><title>We built a distributed page cache, then deleted it</title><link>https://koray.dev/posts/the-page-cache-we-deleted/</link><guid isPermaLink="true">https://koray.dev/posts/the-page-cache-we-deleted/</guid><description>Three rounds of tuning to cut the write bill, then removal. The same machinery stayed for images.</description><pubDate>Thu, 14 May 2026 06:00:00 GMT</pubDate></item><item><title>Your error handler is inside the cache</title><link>https://koray.dev/posts/your-error-handler-is-inside-the-cache/</link><guid isPermaLink="true">https://koray.dev/posts/your-error-handler-is-inside-the-cache/</guid><description>A container restart took thirty seconds. The site stayed broken for an hour after it came back.</description><pubDate>Thu, 23 Apr 2026 06:00:00 GMT</pubDate></item><item><title>A missing capability beats a threshold</title><link>https://koray.dev/posts/a-missing-capability-beats-a-threshold/</link><guid isPermaLink="true">https://koray.dev/posts/a-missing-capability-beats-a-threshold/</guid><description>A limit can be misconfigured, and mine throttled the one thing that was supposed to recover from the problem it was throttling.</description><pubDate>Sat, 04 Apr 2026 06:00:00 GMT</pubDate></item><item><title>Idempotent writes don&apos;t make side effects idempotent</title><link>https://koray.dev/posts/idempotent-writes-idempotent-side-effects/</link><guid isPermaLink="true">https://koray.dev/posts/idempotent-writes-idempotent-side-effects/</guid><description>The upsert was the easy half. The write also caused four other things, and none of them were idempotent for free.</description><pubDate>Thu, 19 Mar 2026 06:00:00 GMT</pubDate></item><item><title>Math.floor is not a floor</title><link>https://koray.dev/posts/math-floor-is-not-a-floor/</link><guid isPermaLink="true">https://koray.dev/posts/math-floor-is-not-a-floor/</guid><description>The obvious fix drops a step. The clever fix rounds past the input. Neither raises an exception, and only one of them spends money you don&apos;t have.</description><pubDate>Thu, 26 Feb 2026 06:00:00 GMT</pubDate></item></channel></rss>