<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Design · XB Field Notes</title><link>https://hk.xbcatm.com/tags/design/</link><description>Illustrated field notes on HTTP, DNS, TLS, Caddy, SSH, releases, and recovery.</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://hk.xbcatm.com/tags/design/index.xml" rel="self" type="application/rss+xml"/><item><title>Reliable defaults beat clever recovery</title><link>https://hk.xbcatm.com/notes/reliable-defaults-beat-clever-recovery/</link><pubDate>Mon, 20 Jul 2026 00:00:00 +0000</pubDate><guid>https://hk.xbcatm.com/notes/reliable-defaults-beat-clever-recovery/</guid><description>A predictable first path prevents more incidents than a complicated fallback can repair.</description><content:encoded>&lt;p&gt;Small services often accumulate recovery logic before their normal path is fully understood. Every retry, alternate endpoint, and compatibility branch adds another state that must be observed and tested.&lt;/p&gt;
&lt;figure class="technical-diagram"&gt;&lt;img loading="lazy" src="https://hk.xbcatm.com/visuals/reliable-path.detail.en.svg" alt="The common path builds from pinned tools, validates a complete directory, publishes and verifies public responses, and retains the previous directory. Configuration, runtime and documentation agree on one selected release. Failure first asks whether it is transient and safe to repeat. Only then can retries consume an attempt-and-time budget; otherwise stop and correct. Permission errors are excluded. A lost response may already conceal success. Recovery explicitly returns to the retained known-good directory and records the outcome." width="720" height="3620"&gt;&lt;figcaption&gt;Keep the common path visible. Qualify and bound retries, then recover to a retained known-good state rather than a partial copy.&lt;/figcaption&gt;&lt;/figure&gt;
&lt;h2 id="make-the-common-path-boring"&gt;Make the common path boring&lt;/h2&gt;
&lt;p&gt;A useful default is explicit, easy to inspect, and safe to repeat. For a static site, that can be as simple as:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Build from a pinned toolchain.&lt;/li&gt;
&lt;li&gt;Check the generated HTML, assets, and complete staged directory.&lt;/li&gt;
&lt;li&gt;Publish that directory, then verify public responses against it.&lt;/li&gt;
&lt;li&gt;Keep the previous directory available for rollback.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The sequence is less impressive than a multi-stage deployment system, but its state is visible. When something fails, the operator can answer whether the problem is in the source, the build, the copy, or the web server.&lt;/p&gt;
&lt;h2 id="retry-only-a-bounded-operation"&gt;Retry only a bounded operation&lt;/h2&gt;
&lt;p&gt;Retries are useful when the failure may be transient and repeating the operation preserves its intended effect. Idempotence does not mean every response or incidental log entry is identical; after a lost response, the first attempt may already have succeeded. A download from an origin may be safe to retry; a database migration may not be. Treating every error as retryable hides the boundary that needs attention.&lt;/p&gt;
&lt;p&gt;When a retry is appropriate, record the attempt count and the final reason. A log entry such as &amp;ldquo;publish failed: checksum mismatch&amp;rdquo; is more actionable than a sequence of silent retries followed by a generic timeout.&lt;/p&gt;
&lt;h2 id="prefer-one-authoritative-state"&gt;Prefer one authoritative state&lt;/h2&gt;
&lt;p&gt;Configuration, runtime state, and documentation should agree about which directory is live and which command produces it. If a release can be copied to three different paths depending on who runs it, recovery becomes guesswork.&lt;/p&gt;
&lt;p&gt;For a static deployment, a short release record is enough:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;release: 2026-07-20
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;source: git commit &amp;lt;commit-id&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;builder: Hugo 0.165.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;output: public/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;verification: links + headers + checksums
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The placeholder commit ID is deliberately resolved at release time instead of being invented in documentation.&lt;/p&gt;
&lt;h2 id="recovery-should-restore-a-known-state"&gt;Recovery should restore a known state&lt;/h2&gt;
&lt;p&gt;Recovery is easiest when it returns the service to the last known-good directory, not when it chooses among several partially built alternatives. Keep the previous output until the new output has passed its checks, then remove old copies according to a retention policy.&lt;/p&gt;
&lt;p&gt;The goal is not to eliminate failure. It is to make the failure small enough to explain and the recovery small enough to trust.&lt;/p&gt;
&lt;p&gt;Bound retries by both attempts and elapsed time. Use backoff with jitter when many clients could retry together, and avoid stacking retries at every layer. Permission errors and deterministic bad input need correction, not a longer retry loop.&lt;/p&gt;
&lt;h2 id="sources"&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html"&gt;RFC 9110 — HTTP Semantics&lt;/a&gt;, section 9.2.2 on idempotent methods and retries, checked 2026-07-20.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://hk.xbcatm.com/resources/"&gt;Static-site release checklist&lt;/a&gt;, local companion resource.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/builders-library/timeouts-retries-and-backoff-with-jitter/"&gt;AWS Builders’ Library: Timeouts, retries, and backoff with jitter&lt;/a&gt;, retry amplification, bounded retry budgets, backoff, and jitter, checked 2026-10-15.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item></channel></rss>