<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>The Book Shelf — Matej Murn</title>
    <link>https://murn.eu/blog</link>
    <description>Thoughts on design, technology, free time, and a little philosophy.</description>
    <language>en</language>
    <atom:link href="https://murn.eu/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>What survives a port is the asset</title>
      <link>https://murn.eu/blog/port-test</link>
      <guid isPermaLink="true">https://murn.eu/blog/port-test</guid>
      <pubDate>Sat, 04 Jul 2026 00:00:00 GMT</pubDate>
      <description>The same repo holds the API twice — NestJS and a Spring Boot port serving one hand-written contract. What transferred unchanged between them is where the engineering actually lives.</description>
      <category>engineering</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>Staging should run NODE_ENV=production</title>
      <link>https://murn.eu/blog/two-envs</link>
      <guid isPermaLink="true">https://murn.eu/blog/two-envs</guid>
      <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
      <description>NODE_ENV is a semantics switch that libraries branch on, not a deployment tier. Set it to staging and your rehearsal runs different code paths than the show.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Every knob is a promise</title>
      <link>https://murn.eu/blog/knob-debt</link>
      <guid isPermaLink="true">https://murn.eu/blog/knob-debt</guid>
      <pubDate>Sat, 27 Jun 2026 00:00:00 GMT</pubDate>
      <description>The retry policy is three hardcoded constants, and the decision record says why: a config option promises that every value works. Unused knobs are debt, not flexibility.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Refresh on the publisher&apos;s clock</title>
      <link>https://murn.eu/blog/upstream-clock</link>
      <guid isPermaLink="true">https://murn.eu/blog/upstream-clock</guid>
      <pubDate>Tue, 23 Jun 2026 00:00:00 GMT</pubDate>
      <description>The weather source publishes on a ~25-minute cycle, so the refresh cron fires at :27 — cache freshness is a property of the upstream&apos;s rhythm, not of your TTL.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Validate 86 fields to serve 6</title>
      <link>https://murn.eu/blog/boundary-tripwire</link>
      <guid isPermaLink="true">https://murn.eu/blog/boundary-tripwire</guid>
      <pubDate>Sat, 20 Jun 2026 00:00:00 GMT</pubDate>
      <description>The API returns six fields per station but validates the upstream&apos;s entire shape. Drift in the eighty fields you ignore is the earliest warning about the six you depend on.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Missing is not zero</title>
      <link>https://murn.eu/blog/typed-absence</link>
      <guid isPermaLink="true">https://murn.eu/blog/typed-absence</guid>
      <pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate>
      <description>One weather station reports no temperature at all. Encode that as 0 or drop the key, and every consumer inherits the bug — absence belongs in the contract, typed.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Generated specs drift away from review</title>
      <link>https://murn.eu/blog/drift-direction</link>
      <guid isPermaLink="true">https://murn.eu/blog/drift-direction</guid>
      <pubDate>Sat, 13 Jun 2026 00:00:00 GMT</pubDate>
      <description>Doc generation doesn&apos;t stop code and contract from disagreeing — it decides which one drifts unreviewed. The artifact a stakeholder approved should be the one the code chases.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Undocumented decisions get made twice</title>
      <link>https://murn.eu/blog/relitigation</link>
      <guid isPermaLink="true">https://murn.eu/blog/relitigation</guid>
      <pubDate>Tue, 09 Jun 2026 00:00:00 GMT</pubDate>
      <description>My test folder got migrated twice — same move, same commit message, days apart. An agent session starts with no memory, and an unwritten decision is just an accident it feels free to fix.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>The AI plan is for keeping, not following</title>
      <link>https://murn.eu/blog/control-plan</link>
      <guid isPermaLink="true">https://murn.eu/blog/control-plan</guid>
      <pubDate>Sat, 06 Jun 2026 00:00:00 GMT</pubDate>
      <description>I had the model write its full project plan, committed it, and added a rule to never follow it. The unedited default is what makes judgment visible.</description>
      <category>engineering</category>
      <category>philosophy</category>
    </item>
    <item>
      <title>Disposable by default</title>
      <link>https://murn.eu/blog/disposable</link>
      <guid isPermaLink="true">https://murn.eu/blog/disposable</guid>
      <pubDate>Tue, 02 Jun 2026 00:00:00 GMT</pubDate>
      <description>Vibe coding versus agentic engineering is sold as a skill tier. It is really a per-artifact call: most agent output is disposable, and verification only pays once an output crosses the boundary where a second reader has to trust it.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Ship the answer with the question</title>
      <link>https://murn.eu/blog/executable-questions</link>
      <guid isPermaLink="true">https://murn.eu/blog/executable-questions</guid>
      <pubDate>Tue, 02 Jun 2026 00:00:00 GMT</pubDate>
      <description>The brief&apos;s openapi.yaml was missing, so I committed my own. A question that ships with its answer turns authoring into a veto — and never blocks.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>Pattern shopping</title>
      <link>https://murn.eu/blog/pattern-shopping</link>
      <guid isPermaLink="true">https://murn.eu/blog/pattern-shopping</guid>
      <pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate>
      <description>Pattern catalogs read forward — name, then move, then constraint. Engineering runs the other way. Reading them as curriculum produces moves imported from a vocabulary rather than earned from a failure.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Rule drift</title>
      <link>https://murn.eu/blog/rule-drift</link>
      <guid isPermaLink="true">https://murn.eu/blog/rule-drift</guid>
      <pubDate>Mon, 25 May 2026 00:00:00 GMT</pubDate>
      <description>Osmani&apos;s ratchet — every mistake becomes a rule — is the accretion move. The second move is consolidation: rules that live in one canonical file cannot drift, and most harness write-ups skip it.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Thinking in code</title>
      <link>https://murn.eu/blog/thinking-in-code</link>
      <guid isPermaLink="true">https://murn.eu/blog/thinking-in-code</guid>
      <pubDate>Sat, 23 May 2026 00:00:00 GMT</pubDate>
      <description>For ambiguous problems, writing the code is where the thinking happens — not a transcription step after the thinking has finished. The medium and the thought go together.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Judgement-shaped problems</title>
      <link>https://murn.eu/blog/judgement-shaped-problems</link>
      <guid isPermaLink="true">https://murn.eu/blog/judgement-shaped-problems</guid>
      <pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate>
      <description>Most production &apos;agents&apos; are integrations in costume. The test is where the if/else lives — in code, or in inference.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>LLM catch</title>
      <link>https://murn.eu/blog/the-catch</link>
      <guid isPermaLink="true">https://murn.eu/blog/the-catch</guid>
      <pubDate>Tue, 21 Apr 2026 00:00:00 GMT</pubDate>
      <description>LLMs write perfect plans, detailed specifications, and complete architectures. Nobody ever builds any of it.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Asking is not enough</title>
      <link>https://murn.eu/blog/asking-is-not-enough</link>
      <guid isPermaLink="true">https://murn.eu/blog/asking-is-not-enough</guid>
      <pubDate>Wed, 18 Mar 2026 00:00:00 GMT</pubDate>
      <description>Most LLM workflows fail not because the model gets it wrong, but because nobody defined what right looks like before calling it.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Prompts as pipelines</title>
      <link>https://murn.eu/blog/prompts-as-pipelines</link>
      <guid isPermaLink="true">https://murn.eu/blog/prompts-as-pipelines</guid>
      <pubDate>Sun, 01 Mar 2026 00:00:00 GMT</pubDate>
      <description>Prompt engineering is not the art of writing one better prompt — it is the discipline of breaking the work into phases that can fail independently.</description>
      <category>engineering</category>
      <category>llm</category>
    </item>
    <item>
      <title>Boring software</title>
      <link>https://murn.eu/blog/boring</link>
      <guid isPermaLink="true">https://murn.eu/blog/boring</guid>
      <pubDate>Thu, 05 Feb 2026 00:00:00 GMT</pubDate>
      <description>The best software is the kind where nothing happens. Everything was planned, written, tested, and deployed — and it just works.</description>
      <category>engineering</category>
    </item>
    <item>
      <title>On simplicity</title>
      <link>https://murn.eu/blog/on-simplicity</link>
      <guid isPermaLink="true">https://murn.eu/blog/on-simplicity</guid>
      <pubDate>Sat, 10 Jan 2026 00:00:00 GMT</pubDate>
      <description>Simplicity is not the absence of complexity — it is the resolution of it.</description>
      <category>design</category>
    </item>
    <item>
      <title>Return value</title>
      <link>https://murn.eu/blog/return-value</link>
      <guid isPermaLink="true">https://murn.eu/blog/return-value</guid>
      <pubDate>Mon, 05 Jan 2026 00:00:00 GMT</pubDate>
      <description>Most blog posts get published because the writer wrote them. This blog is built around a different test — would the reader keep it?</description>
      <category>philosophy</category>
    </item>
  </channel>
</rss>
