<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Inkcairn Demo</title>
    <link>https://inkcairn.so1ve.dev/</link>
    <description>Notes on programming languages, small tools, and thoughtful software.</description>
    
      <item>
        <title>A small Markdown showcase</title>
        <link>https://inkcairn.so1ve.dev/posts/markdown-showcase.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/markdown-showcase.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        
        <content:encoded>&#60;h2 id=&#34;heading-2&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#heading-2&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Heading 2&#60;/h2&#62;
&#60;h3 id=&#34;heading-3&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#heading-3&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Heading 3&#60;/h3&#62;
&#60;h4 id=&#34;heading-4&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#heading-4&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Heading 4&#60;/h4&#62;
&#60;h5 id=&#34;heading-5&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#heading-5&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Heading 5&#60;/h5&#62;
&#60;h6 id=&#34;heading-6&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#heading-6&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Heading 6&#60;/h6&#62;
&#60;h2 id=&#34;text&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#text&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Text&#60;/h2&#62;
&#60;p&#62;A paragraph can include &#60;strong&#62;strong emphasis&#60;/strong&#62;, &#60;em&#62;gentle emphasis&#60;/em&#62;,
&#60;em&#62;&#60;strong&#62;both at once&#60;/strong&#62;&#60;/em&#62;, or a &#60;del&#62;thought that did not survive editing&#60;/del&#62;. Names such as
&#60;code&#62;inkcairn.md&#60;/code&#62; belong comfortably inline, while an
&#60;a href=&#34;https://commonmark.org/&#34;&#62;ordinary link&#60;/a&#62; and an automatic link such as
&#60;a href=&#34;https://www.rust-lang.org/&#34;&#62;https://www.rust-lang.org/&#60;/a&#62; remain easy to spot in the source.&#60;/p&#62;
&#60;hr /&#62;
&#60;h2 id=&#34;lists-and-small-plans&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#lists-and-small-plans&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Lists and small plans&#60;/h2&#62;
&#60;p&#62;An unordered list works well for a collection whose order does not matter:&#60;/p&#62;
&#60;ul&#62;
&#60;li&#62;Plain text files&#60;/li&#62;
&#60;li&#62;A predictable directory layout&#60;/li&#62;
&#60;li&#62;A build that leaves the source untouched
&#60;ul&#62;
&#60;li&#62;Posts stay under &#60;code&#62;posts/&#60;/code&#62;&#60;/li&#62;
&#60;li&#62;Images stay under &#60;code&#62;assets/&#60;/code&#62;&#60;/li&#62;
&#60;/ul&#62;
&#60;/li&#62;
&#60;/ul&#62;
&#60;p&#62;Use an ordered list when sequence does matter:&#60;/p&#62;
&#60;ol&#62;
&#60;li&#62;Write the first draft.&#60;/li&#62;
&#60;li&#62;Read it away from the editor.&#60;/li&#62;
&#60;li&#62;Publish only when it says what you meant.&#60;/li&#62;
&#60;/ol&#62;
&#60;p&#62;A task list can hold the last few details:&#60;/p&#62;
&#60;ul class=&#34;contains-task-list&#34;&#62;
&#60;li class=&#34;task-list-item&#34;&#62;&#60;input type=&#34;checkbox&#34; class=&#34;task-list-item-checkbox&#34; checked=&#34;&#34; disabled=&#34;&#34; /&#62; Choose a title&#60;/li&#62;
&#60;li class=&#34;task-list-item&#34;&#62;&#60;input type=&#34;checkbox&#34; class=&#34;task-list-item-checkbox&#34; checked=&#34;&#34; disabled=&#34;&#34; /&#62; Add a useful example&#60;/li&#62;
&#60;li class=&#34;task-list-item&#34;&#62;&#60;input type=&#34;checkbox&#34; class=&#34;task-list-item-checkbox&#34; disabled=&#34;&#34; /&#62; Stop polishing and publish&#60;/li&#62;
&#60;/ul&#62;
&#60;h2 id=&#34;quotations-and-callouts&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#quotations-and-callouts&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Quotations and callouts&#60;/h2&#62;
&#60;blockquote&#62;
&#60;p&#62;Good tools leave more room for the work itself.&#60;/p&#62;
&#60;p&#62;A blockquote can hold more than one paragraph, but it should still earn the
interruption.&#60;/p&#62;
&#60;/blockquote&#62;
&#60;div class=&#34;markdown-alert markdown-alert-tip&#34;&#62;
&#60;p class=&#34;markdown-alert-title&#34;&#62;Tip&#60;/p&#62;
&#60;p&#62;Keep the source simple enough to understand in any text editor. The rendered
page can take care of the presentation.&#60;/p&#62;
&#60;/div&#62;
&#60;h2 id=&#34;tables&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#tables&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Tables&#60;/h2&#62;
&#60;p&#62;Tables are handy for compact comparisons rather than long prose:&#60;/p&#62;
&#60;table&#62;
&#60;thead&#62;
&#60;tr&#62;
&#60;th align=&#34;left&#34;&#62;Source&#60;/th&#62;
&#60;th align=&#34;center&#34;&#62;Result&#60;/th&#62;
&#60;th align=&#34;right&#34;&#62;Kept in Git&#60;/th&#62;
&#60;/tr&#62;
&#60;/thead&#62;
&#60;tbody&#62;
&#60;tr&#62;
&#60;td align=&#34;left&#34;&#62;Markdown&#60;/td&#62;
&#60;td align=&#34;center&#34;&#62;Article&#60;/td&#62;
&#60;td align=&#34;right&#34;&#62;Yes&#60;/td&#62;
&#60;/tr&#62;
&#60;tr&#62;
&#60;td align=&#34;left&#34;&#62;Image&#60;/td&#62;
&#60;td align=&#34;center&#34;&#62;Static asset&#60;/td&#62;
&#60;td align=&#34;right&#34;&#62;Yes&#60;/td&#62;
&#60;/tr&#62;
&#60;tr&#62;
&#60;td align=&#34;left&#34;&#62;Generated HTML&#60;/td&#62;
&#60;td align=&#34;center&#34;&#62;Published site&#60;/td&#62;
&#60;td align=&#34;right&#34;&#62;No&#60;/td&#62;
&#60;/tr&#62;
&#60;/tbody&#62;
&#60;/table&#62;
&#60;h2 id=&#34;code-and-diffs&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#code-and-diffs&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Code and diffs&#60;/h2&#62;
&#60;p&#62;Fenced blocks keep code readable and add syntax highlighting to the page:&#60;/p&#62;
&#60;pre data-language=&#34;typescript&#34;&#62;&#60;button class=&#34;copy-code&#34; type=&#34;button&#34; aria-label=&#34;Copy code&#34; title=&#34;Copy code&#34;&#62;&#60;svg class=&#34;copy-icon&#34; viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&#62;&#60;g transform=&#34;translate(1 1)&#34;&#62;&#60;rect x=&#34;5&#34; y=&#34;5&#34; width=&#34;8&#34; height=&#34;8&#34; rx=&#34;1&#34;&#62;&#60;/rect&#62;&#60;path d=&#34;M3 11H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v1&#34;&#62;&#60;/path&#62;&#60;/g&#62;&#60;/svg&#62;&#60;svg class=&#34;copy-success&#34; viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&#62;&#60;path d=&#34;m2.5 8 3 3 8-8&#34;&#62;&#60;/path&#62;&#60;/svg&#62;&#60;/button&#62;&#60;code&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;type&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;Post&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;=&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;{&#60;/span&#62;&#60;/span&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;  &#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;title&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;:&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0550ae,#79c0ff);&#34;&#62;string&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;  &#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;published&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;:&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;Date&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;}&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;/span&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;const&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#8250df,#d2a8ff);&#34;&#62;describe&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;=&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;(&#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;post&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;:&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;Post&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;)&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;=&#38;gt;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;`&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;${&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;post&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;.&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;title&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;}&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62; · &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;${&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;post&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;.&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;published&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;.&#60;/span&#62;&#60;span style=&#34;color:light-dark(#8250df,#d2a8ff);&#34;&#62;getFullYear&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;()&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;}&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;`&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;/code&#62;&#60;/pre&#62;
&#60;p&#62;When the change matters more than the surrounding file, a diff says it directly:&#60;/p&#62;
&#60;pre data-language=&#34;ts&#34;&#62;&#60;button class=&#34;copy-code&#34; type=&#34;button&#34; aria-label=&#34;Copy code&#34; title=&#34;Copy code&#34;&#62;&#60;svg class=&#34;copy-icon&#34; viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&#62;&#60;g transform=&#34;translate(1 1)&#34;&#62;&#60;rect x=&#34;5&#34; y=&#34;5&#34; width=&#34;8&#34; height=&#34;8&#34; rx=&#34;1&#34;&#62;&#60;/rect&#62;&#60;path d=&#34;M3 11H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v1&#34;&#62;&#60;/path&#62;&#60;/g&#62;&#60;/svg&#62;&#60;svg class=&#34;copy-success&#34; viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&#62;&#60;path d=&#34;m2.5 8 3 3 8-8&#34;&#62;&#60;/path&#62;&#60;/svg&#62;&#60;/button&#62;&#60;code&#62;&#60;span class=&#34;code-line diff diff-del&#34;&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;const&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0550ae,#79c0ff);&#34;&#62;status&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;=&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;&#38;quot;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;draft&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;&#38;quot;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;span class=&#34;code-line diff diff-add&#34;&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;const&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0550ae,#79c0ff);&#34;&#62;status&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;=&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;&#38;quot;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;published&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;&#38;quot;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;/code&#62;&#60;/pre&#62;
&#60;h2 id=&#34;images-and-hidden-details&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#images-and-hidden-details&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Images and hidden details&#60;/h2&#62;
&#60;p&#62;Images use the same familiar syntax as links:&#60;/p&#62;
&#60;p&#62;&#60;img src=&#34;/assets/inkcairn.svg&#34; alt=&#34;The Inkcairn mark&#34; /&#62;&#60;/p&#62;
&#60;details&#62;
  &#60;summary&#62;Some details can wait until they are wanted.&#60;/summary&#62;
  &#60;p&#62;This small HTML element is useful for an aside that would otherwise interrupt the article.&#60;/p&#62;
&#60;/details&#62;
&#60;h2 id=&#34;footnotes&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#footnotes&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Footnotes&#60;/h2&#62;
&#60;p&#62;A footnote keeps a useful aside nearby without forcing it into the sentence.&#60;sup class=&#34;footnote-ref&#34;&#62;&#60;a href=&#34;#fn-1&#34; id=&#34;fnref-1&#34; data-footnote-ref&#62;1&#60;/a&#62;&#60;/sup&#62;
The reader can follow it and return to exactly the same place.&#60;/p&#62;
&#60;section class=&#34;footnotes&#34; data-footnotes&#62;
&#60;ol&#62;
&#60;li id=&#34;fn-1&#34;&#62;
&#60;p&#62;Footnotes can contain links, emphasis, and other ordinary Markdown. &#60;a href=&#34;#fnref-1&#34; class=&#34;footnote-backref&#34; data-footnote-backref data-footnote-backref-idx=&#34;1&#34; aria-label=&#34;Back to reference 1&#34;&#62;↩&#60;/a&#62;&#60;/p&#62;
&#60;/li&#62;
&#60;/ol&#62;
&#60;/section&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Borrowing notes</title>
        <link>https://inkcairn.so1ve.dev/posts/Programming%20Languages/Rust/borrowing-notes.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/Programming%20Languages/Rust/borrowing-notes.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>Borrowing is easiest to understand as a statement about relationships rather than punctuation. A reference says that some value remains owned elsewhere and that the current code may use it under a particular set of rules.</description>
        <content:encoded>&#60;h2 id=&#34;ownership&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#ownership&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Ownership&#60;/h2&#62;
&#60;p&#62;Ownership makes resource lifetimes explicit without requiring a garbage
collector. More importantly, it gives APIs a vocabulary for saying who may keep
a value, who may change it, and when cleanup happens.&#60;/p&#62;
&#60;h2 id=&#34;a-useful-question&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#a-useful-question&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;A useful question&#60;/h2&#62;
&#60;p&#62;When a lifetime annotation feels difficult, ask what relationship the returned
value actually has to the inputs. The compiler is often pointing at an unclear
contract rather than demanding more syntax.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Error messages are part of the interface</title>
        <link>https://inkcairn.so1ve.dev/posts/Programming%20Languages/Rust/error-messages-as-interface.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/Programming%20Languages/Rust/error-messages-as-interface.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>An error variant may be designed for a program, but its final message is read by a person who needs to decide what to do next. That makes wording and context part of the interface rather than decoration added at the end.</description>
        <content:encoded>&#60;h2 id=&#34;name-the-failed-operation&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#name-the-failed-operation&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Name the failed operation&#60;/h2&#62;
&#60;p&#62;“Invalid input” says almost nothing. “Cannot read &#60;code&#62;notes/index.md&#60;/code&#62;” identifies
both the attempted operation and its target. The underlying operating-system
error can then explain why it failed.&#60;/p&#62;
&#60;h2 id=&#34;context-should-earn-its-place&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#context-should-earn-its-place&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Context should earn its place&#60;/h2&#62;
&#60;p&#62;Repeatedly wrapping the same error makes a message longer without making it more
useful. Add context at the boundary that knows the concrete operation; let clear
errors pass through intermediate layers unchanged.&#60;/p&#62;
&#60;pre data-language=&#34;rust&#34;&#62;&#60;button class=&#34;copy-code&#34; type=&#34;button&#34; aria-label=&#34;Copy code&#34; title=&#34;Copy code&#34;&#62;&#60;svg class=&#34;copy-icon&#34; viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&#62;&#60;g transform=&#34;translate(1 1)&#34;&#62;&#60;rect x=&#34;5&#34; y=&#34;5&#34; width=&#34;8&#34; height=&#34;8&#34; rx=&#34;1&#34;&#62;&#60;/rect&#62;&#60;path d=&#34;M3 11H2a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v1&#34;&#62;&#60;/path&#62;&#60;/g&#62;&#60;/svg&#62;&#60;svg class=&#34;copy-success&#34; viewBox=&#34;0 0 16 16&#34; aria-hidden=&#34;true&#34;&#62;&#60;path d=&#34;m2.5 8 3 3 8-8&#34;&#62;&#60;/path&#62;&#60;/svg&#62;&#60;/button&#62;&#60;code&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;let&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;source&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;=&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#953800,#ffa657);&#34;&#62;fs&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;::&#60;/span&#62;&#60;span style=&#34;color:light-dark(#8250df,#d2a8ff);&#34;&#62;read_to_string&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;(&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;path&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;)&#60;/span&#62;&#60;/span&#62;&#60;span class=&#34;code-line&#34;&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;    &#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;.&#60;/span&#62;&#60;span style=&#34;color:light-dark(#8250df,#d2a8ff);&#34;&#62;with_context&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;(&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;||&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#8250df,#d2a8ff);&#34;&#62;format!&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;(&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;&#38;quot;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;cannot read &#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;{}&#60;/span&#62;&#60;span style=&#34;color:light-dark(#0a3069,#a5d6ff);&#34;&#62;&#38;quot;&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;,&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62; &#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;path&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;.&#60;/span&#62;&#60;span style=&#34;color:light-dark(#8250df,#d2a8ff);&#34;&#62;display&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;()&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;)&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;)&#60;/span&#62;&#60;span style=&#34;color:light-dark(#cf222e,#ff7b72);&#34;&#62;?&#60;/span&#62;&#60;span style=&#34;color:light-dark(#1f2328,#e6edf3);&#34;&#62;;&#60;/span&#62;&#60;/span&#62;&#60;/code&#62;&#60;/pre&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Types and text</title>
        <link>https://inkcairn.so1ve.dev/posts/Programming%20Languages/types-and-text.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/Programming%20Languages/types-and-text.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>Text is rarely “just a string.” The moment a program needs to compare, display, slice, normalize, or persist it, an implicit model of text becomes part of the design.</description>
        <content:encoded>&#60;h2 id=&#34;a-small-observation&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#a-small-observation&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;A small observation&#60;/h2&#62;
&#60;p&#62;Good representations make the common operation obvious. A path is not merely
text, a user-facing label is not an identifier, and bytes received from the
outside world do not become valid Unicode because a convenient API expects a
&#60;code&#62;String&#60;/code&#62;.&#60;/p&#62;
&#60;p&#62;Types are most valuable here when they preserve a distinction the program would
otherwise have to remember everywhere.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>What a type name promises</title>
        <link>https://inkcairn.so1ve.dev/posts/Programming%20Languages/what-a-type-name-promises.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/Programming%20Languages/what-a-type-name-promises.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>A type name is a small promise about the values a program may contain. When the name and the representation disagree, every caller must quietly repair that promise in its own head.</description>
        <content:encoded>&#60;h2 id=&#34;prefer-the-domain-word&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#prefer-the-domain-word&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Prefer the domain word&#60;/h2&#62;
&#60;p&#62;&#60;code&#62;String&#60;/code&#62; describes storage. &#60;code&#62;Slug&#60;/code&#62;, &#60;code&#62;RepositoryUrl&#60;/code&#62;, and &#60;code&#62;PublishedDate&#60;/code&#62;
describe roles. A newtype is worthwhile when the role carries an invariant or
prevents two identical representations from being confused.&#60;/p&#62;
&#60;p&#62;It is less useful when it only moves getters and constructors around without
removing decisions from callers.&#60;/p&#62;
&#60;h2 id=&#34;read-the-signatures-together&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#read-the-signatures-together&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Read the signatures together&#60;/h2&#62;
&#60;p&#62;One function signature can look reasonable in isolation. A module&#39;s full set of
signatures reveals whether its vocabulary is coherent or whether the same idea
appears under several names.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Defaults are part of the interface</title>
        <link>https://inkcairn.so1ve.dev/posts/defaults-are-part-of-the-interface.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/defaults-are-part-of-the-interface.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>A default is a decision made on behalf of every person who does not stop to configure the software. That makes it more important than most advanced options, even when it occupies only one line of code.</description>
        <content:encoded>&#60;h2 id=&#34;the-common-path&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#the-common-path&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;The common path&#60;/h2&#62;
&#60;p&#62;Good defaults make the common path obvious and safe. They should express what
the program believes most people mean, while leaving an honest route to the less
common cases.&#60;/p&#62;
&#60;p&#62;The difficult part is resisting defaults that merely hide uncertainty. If the
program cannot infer an important choice, asking once is kinder than guessing
forever.&#60;/p&#62;
&#60;h2 id=&#34;configuration-has-a-cost&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#configuration-has-a-cost&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Configuration has a cost&#60;/h2&#62;
&#60;p&#62;Every option adds documentation, combinations, and states that future changes
must preserve. Before adding one, it is worth asking whether the underlying
behavior is actually stable enough to deserve a permanent switch.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Reading old code slowly</title>
        <link>https://inkcairn.so1ve.dev/posts/reading-old-code.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/reading-old-code.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>Old code is easiest to misunderstand when approached as a cleanup exercise. Before changing it, I try to learn which constraints shaped it and which of those constraints still exist.</description>
        <content:encoded>&#60;h2 id=&#34;begin-at-the-boundary&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#begin-at-the-boundary&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Begin at the boundary&#60;/h2&#62;
&#60;p&#62;The public entry point usually tells a clearer story than the helpers beneath
it. Follow one ordinary input through the program before collecting suspicious
functions or unusual branches.&#60;/p&#62;
&#60;h2 id=&#34;keep-an-evidence-list&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#keep-an-evidence-list&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Keep an evidence list&#60;/h2&#62;
&#60;p&#62;I write down three kinds of observations:&#60;/p&#62;
&#60;ul&#62;
&#60;li&#62;behavior that callers visibly depend on;&#60;/li&#62;
&#60;li&#62;complexity caused by a requirement that still exists;&#60;/li&#62;
&#60;li&#62;complexity whose original requirement can no longer be found.&#60;/li&#62;
&#60;/ul&#62;
&#60;p&#62;The third list is where simplification begins, but only after the first two are
understood.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>A small essay worth keeping</title>
        <link>https://inkcairn.so1ve.dev/posts/reposted-essay.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/reposted-essay.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>Reposted from An essay from somewhere else by Alex Example, published 2024-06-15: https://example.com/original-essay. This fictional repost demonstrates how Inkcairn credits an original author and points readers back to the source without hiding the local copy.</description>
        <content:encoded>
&#60;aside class=&#34;repost-notice&#34; aria-label=&#34;Original source&#34;&#62;
  Reposted from &#60;a href=&#34;https://example.com/original-essay&#34; rel=&#34;external&#34;&#62;An essay from somewhere else&#60;/a&#62; by Alex Example, published &#60;time datetime=&#34;2024-06-15T00:00:00Z&#34;&#62;2024-06-15&#60;/time&#62;.
&#60;/aside&#62;&#60;h2 id=&#34;keep-the-source-visible&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#keep-the-source-visible&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Keep the source visible&#60;/h2&#62;
&#60;p&#62;A repost should make its origin obvious before the reader reaches the article
body. Attribution is part of the content, not a footnote added as an
afterthought.&#60;/p&#62;
&#60;p&#62;The local page can remain useful for reading and searching while its canonical
URL identifies the original publication.&#60;/p&#62;
&#60;h2 id=&#34;preserve-the-reading-experience&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#preserve-the-reading-experience&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Preserve the reading experience&#60;/h2&#62;
&#60;p&#62;Good syndication keeps the article readable, carries its source into feeds, and
avoids presenting someone else&#39;s work as original writing.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Tools that disappear</title>
        <link>https://inkcairn.so1ve.dev/posts/tools-that-disappear.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/tools-that-disappear.html</guid>
        <pubDate>Thu, 10 Sep 2026 17:59:16 +0800</pubDate>
        <description>The small tools I trust most become almost invisible during use. They preserve the shape of the task, respond quickly, and leave behind results that do not depend on the tool remaining installed forever.</description>
        <content:encoded>&#60;h2 id=&#34;quiet-by-design&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#quiet-by-design&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Quiet by design&#60;/h2&#62;
&#60;p&#62;A quiet tool does not need to be featureless. It can have strong opinions while
keeping those opinions close to the problem it solves.&#60;/p&#62;
&#60;p&#62;The difference is visible in the output: ordinary files, familiar protocols,
and names that still make sense when inspected by hand.&#60;/p&#62;
&#60;h2 id=&#34;a-useful-test&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#a-useful-test&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;A useful test&#60;/h2&#62;
&#60;p&#62;If removing the tool would also make its output difficult to understand, the
tool may have captured too much of the work.&#60;/p&#62;
</content:encoded>
      </item>
    
      <item>
        <title>Software that keeps working</title>
        <link>https://inkcairn.so1ve.dev/posts/software-that-keeps-working.html</link>
        <guid>https://inkcairn.so1ve.dev/posts/software-that-keeps-working.html</guid>
        <pubDate>Thu, 14 Sep 2023 00:00:00 +0000</pubDate>
        <description>Longevity rarely comes from predicting every future requirement. It comes from choosing inputs and outputs that remain understandable when the implementation between them has to change.</description>
        <content:encoded>&#60;h2 id=&#34;durable-edges&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#durable-edges&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Durable edges&#60;/h2&#62;
&#60;p&#62;Plain text, documented URLs, and standard formats are not exciting choices, but
they give future software something stable to meet. The internals can then be
rewritten without turning every old document into a migration project.&#60;/p&#62;
&#60;h2 id=&#34;fewer-hidden-obligations&#34;&#62;&#60;a class=&#34;anchor&#34; href=&#34;#fewer-hidden-obligations&#34; aria-hidden=&#34;true&#34;&#62;#&#60;/a&#62;Fewer hidden obligations&#60;/h2&#62;
&#60;p&#62;Persistence creates promises. A cache can be deleted; an authored document
cannot. Treating those two kinds of data differently keeps defensive machinery
focused where losing information would actually matter.&#60;/p&#62;
</content:encoded>
      </item>
    
  </channel>
</rss>