<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Alex Leighton's Blog</title>
  <id>https://alexleighton.com/</id>
  <link href="https://alexleighton.com/feed.xml" rel="self" />
  <link href="https://alexleighton.com/" />
  <updated>2026-08-17T01:58:50.026853084Z</updated>
  <author>
    <name>Alex Leighton</name>
    <uri>https://alexleighton.com/</uri>
  </author>
  <icon>https://alexleighton.com/static/icon-dino.png</icon>
  <logo>https://alexleighton.com/static/icon-dino.png</logo>
  
  <entry>
    <title>Sunshine</title>
    <id>https://alexleighton.com/posts/2026-08-16-sunshine.html</id>
    <link href="https://alexleighton.com/posts/2026-08-16-sunshine.html" />
    <published>2026-08-17T00:10:00Z</published>
    <updated>2026-08-17T00:10:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Testing my new camera in the sun.</p><p>Published on <span title="2026-08-17T00:10:00Z">2026-08-17</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Testing my new camera in the sun.</h3><p>Published on <span title="2026-08-17T00:10:00Z">2026-08-17</span><br>Tags: photography, seattle</p><p><a href="../../../img/img_o_01m06gkthxeh8sg43wsa6hq0g6.html"><img src="https://img.alexleighton.com/img_01m06gkwfdfmf88zca7a6q3gma.jpg" alt="A small crab lying dead on a beach, seen from above. It is enveloped by seaweed, part of its shell a dull brick red, its legs and claws a pale orange. Around it are smooth grey and granite-flecked pebbles, coarse sand, and broken white shell fragments."></img></a></p>
<p><a href="../../../img/img_o_01m06n68rgf3naf2s2q9mktb3b.html"><img src="https://img.alexleighton.com/img_01m06n6aj9etttzrb9qzf833sp.jpg" alt="Close-up of a single Queen Anne's lace flower head against a soft green out-of-focus background. The umbel is a dome of tiny white florets tinged pink at the edges, still partly closed, with thin green bracts fanning out beneath it and a slender lime-green stem running down out of frame. One deep purple floret sits at the very centre."></img></a></p>
<p><a href="../../../img/img_o_01m06n6qvkenga6aehqhkbqg1n.html"><img src="https://img.alexleighton.com/img_01m06n6t0ye5y808fbwddxjr3x.jpg" alt="Close-up of a hawthorn branch bearing clusters of ripening haws. The berries range from green through orange to deep red, each with a dark star-shaped crown at its tip, set among lobed green leaves. The branch runs diagonally across the frame against a blurred olive and grey background."></img></a></p>
<p><a href="../../../img/img_o_01m06n77qff0c8fq99wn6wakrh.html"><img src="https://img.alexleighton.com/img_01m06n7aqjebkr0g1bnfg5a88h.jpg" alt="Close-up of thick moss growing along the ridges of tree bark. The moss forms dense cushions in shades of chartreuse and olive, shot through with rust-brown strands, with strips of pale grey-brown bark showing in the shadowed grooves between them."></img></a></p>
<p><a href="../../../img/img_o_01m06gh80rebxr0ga7hgrm3f85.html"><img src="https://img.alexleighton.com/img_01m06ghg51fj7r6ywf169jg5dd.jpg" alt="Sunset over a distant treeline, photographed under a heavy deck of grey cloud. The sun sits just above the horizon in a narrow gap between cloud layers, throwing a burst of amber light across the underside of the clouds. Three radio transmission masts stand in silhouette on the ridge to the right of the sun, with the dark outlines of conifers along the skyline below."></img></a></p><p><a href="https://alexleighton.com/posts/2026-08-16-sunshine.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>termaid Maintenance</title>
    <id>https://alexleighton.com/posts/2026-08-16-termaid-maintenance.html</id>
    <link href="https://alexleighton.com/posts/2026-08-16-termaid-maintenance.html" />
    <published>2026-08-16T23:45:00Z</published>
    <updated>2026-08-16T23:45:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Planning for upstream drift.</p><p>Published on <span title="2026-08-16T23:45:00Z">2026-08-16</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Planning for upstream drift.</h3><p>Published on <span title="2026-08-16T23:45:00Z">2026-08-16</span><br>Tags: article, commentary, llm, ocaml, software-eng, software-eng-auto</p><p>termaid, my <a href="../../../posts/2026-07-20-termaid.html">OCaml port of <code>mermaid.rs</code></a>, is <a href="https://ocaml.org/p/termaid/latest">available on opam</a>! 🙌 With that release, the work shifts to maintenance.</p>
<h2 id="upstream-check">Upstream Check <a class="heading-anchor" href="#upstream-check" aria-hidden="true">#</a></h2>
<p>Given that this is a machine-driven port of an existing piece of code, I wanted to set up some infrastructure so that I'd catch any upstream bug fixes or feature enhancements. So I added an <a href="https://github.com/alexleighton/termaid/blob/main/.github/workflows/upstream-check.yml"><code>upstream-check.yml</code> GitHub Actions workflow</a> to execute <a href="https://github.com/alexleighton/termaid/blob/main/scripts/check_upstream.sh"><code>check_upstream.sh</code></a> and file an issue when it spots a change. The script uses the commit and blob references in <a href="https://github.com/alexleighton/termaid/blob/main/oracle/UPSTREAM"><code>oracle/UPSTREAM</code></a> to determine changes against upstream. When <a href="https://github.com/alexleighton/termaid/actions">the check fires</a>, I'll ask an agent to update the oracle to the new upstream <code>HEAD</code>, use the oracle to generate test cases relevant to the changes, and adjust the OCaml code to make the tests pass.</p><p>...<br><a href="https://alexleighton.com/posts/2026-08-16-termaid-maintenance.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>termaid</title>
    <id>https://alexleighton.com/posts/2026-07-20-termaid.html</id>
    <link href="https://alexleighton.com/posts/2026-07-20-termaid.html" />
    <published>2026-07-21T01:15:00Z</published>
    <updated>2026-07-21T01:15:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Terminal Mermaid rendering for OCaml.</p><p>Published on <span title="2026-07-21T01:15:00Z">2026-07-21</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Terminal Mermaid rendering for OCaml.</h3><p>Published on <span title="2026-07-21T01:15:00Z">2026-07-21</span><br>Tags: article, llm, ocaml, rust, software-eng, software-eng-auto</p><p>I saw <a href="https://simonwillison.net/2026/Jul/16/grok-mermaid">this post</a> from Simon Willison about running <code>mermaid.rs</code> — a utility from Grok Build, xAI's newly open-sourced coding agent harness, as WebAssembly in the browser. The output looks really nice, the Rust code is very self-contained, and I thought it would be interesting to use an agent to convert it to OCaml. The outcome is <a href="../../../projects/termaid.html"><code>termaid</code></a>, a minimal-dependency OCaml library for rendering Mermaid diagrams.</p>
<h2 id="example">Example <a class="heading-anchor" href="#example" aria-hidden="true">#</a></h2>
<p>The package contains a minimal binary that renders a diagram from stdin, alongside the library itself, for use in other programs. Supported diagram types: flowchart/graph, stateDiagram, classDiagram, erDiagram, and sequenceDiagram.</p>
<pre><code class="language-shell">$ termaid &lt;&lt;'EOF'
sequenceDiagram
  A-&gt;&gt;B: ping
  B--&gt;&gt;A: pong
EOF
┌───┐  ┌───┐
│ A │  │ B │
└─┬─┘  └─┬─┘
  │      │
  │ ping │
  ├─────▶│
  │      │
  │ pong │
  │◄╌╌╌╌╌┤
  │      │
┌─┴─┐  ┌─┴─┐
│ A │  │ B │
└───┘  └───┘
</code></pre><p>...<br><a href="https://alexleighton.com/posts/2026-07-20-termaid.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Listening To: Offender</title>
    <id>https://alexleighton.com/posts/2026-07-11-listening-to-offender.html</id>
    <link href="https://alexleighton.com/posts/2026-07-11-listening-to-offender.html" />
    <published>2026-07-11T22:15:00Z</published>
    <updated>2026-07-11T22:15:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>By Dimension</p><p>Published on <span title="2026-07-11T22:15:00Z">2026-07-11</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>By Dimension</h3><p>Published on <span title="2026-07-11T22:15:00Z">2026-07-11</span><br>Tags: listening-to, music</p><a href="https://www.youtube.com/watch?v=d2u3BRGd2rs">Dimension - Offender</a>
<p>Acid techno, drum and bass, inject it into my veins!</p><p><a href="https://alexleighton.com/posts/2026-07-11-listening-to-offender.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Agent Alignment as Security Theater</title>
    <id>https://alexleighton.com/posts/2026-07-11-agent-alignment-as-security-theater.html</id>
    <link href="https://alexleighton.com/posts/2026-07-11-agent-alignment-as-security-theater.html" />
    <published>2026-07-11T22:00:00Z</published>
    <updated>2026-07-11T22:00:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Coding agents can't gatekeep themselves, so stop pretending.</p><p>Published on <span title="2026-07-11T22:00:00Z">2026-07-11</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Coding agents can't gatekeep themselves, so stop pretending.</h3><p>Published on <span title="2026-07-11T22:00:00Z">2026-07-11</span><br>Tags: commentary, llm, quote, security, society, software-eng</p><blockquote>
<p><a href="https://steveklabnik.com/writing/compilers-and-ai-cyber-defense/"><strong>Steve Klabnik</strong> on 2026-07-10</a>:</p><p>It is really unfortunate that, in order to make sure my compiler isn’t going to produce incorrect codegen, this trips the safety guards. I guess that simply saying “hey this is a toy language nobody uses and so it’s fine I’m not hacking anyone” and that not allowing me around the guards is a “good” thing, but at the same time, it is unfortunate if these policies end up making it so that individuals like me can’t make my software as robust as products from large organizations.</p></blockquote>
<p>I think this kind of "alignment", where "sensitive" topics are identified and the model is immediately cut off, is harmful. I'm reminded of my <a href="../../../posts/2026-01-04-unrestricted-llm-interaction-is-unsafe.html">Unrestricted LLM Interaction is Unsafe</a> post — I remain skeptical that you can foolproof these kinds of "alignment" checks such that they are unbreakable. As a result, they are security theater. Determined people can get past the blockages if they try hard enough, while these checks shut down legitimate uses like Klabnik's.</p><p>...<br><a href="https://alexleighton.com/posts/2026-07-11-agent-alignment-as-security-theater.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Convergent Tool Calling</title>
    <id>https://alexleighton.com/posts/2026-07-11-convergent-tool-calling.html</id>
    <link href="https://alexleighton.com/posts/2026-07-11-convergent-tool-calling.html" />
    <published>2026-07-11T19:30:00Z</published>
    <updated>2026-07-11T19:30:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Leaning on JavaScript for LLM-authored micro-programs.</p><p>Published on <span title="2026-07-11T19:30:00Z">2026-07-11</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Leaning on JavaScript for LLM-authored micro-programs.</h3><p>Published on <span title="2026-07-11T19:30:00Z">2026-07-11</span><br>Tags: article, commentary, javascript, kotlin, llm, software-eng, software-eng-auto</p><blockquote>
<p><a href="https://openai.com/index/gpt-5-6"><strong>OpenAI GPT-5.6 Announcement</strong> on 2026-07-09</a>:</p><p>GPT‑5.6 can write and run lightweight programs that coordinate tools, process intermediate results, monitor progress, and choose the next action as work unfolds. This lets tool-heavy tasks advance with fewer tokens, fewer model round trips, and less guidance. Instead of requiring developers to script every step or passing every tool response back through the model, <a href="https://developers.openai.com/api/docs/guides/tools-programmatic-tool-calling">Programmatic Tool Calling</a> in the Responses API can filter large amounts of intermediate data, retain only what matters, and adapt its workflow along the way.</p></blockquote>
<p>I am getting some sweet validation from this feature they revealed. I built a similar system at work recently, and I think it fits coding agent capabilities nicely.</p><p>...<br><a href="https://alexleighton.com/posts/2026-07-11-convergent-tool-calling.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Listening To: Superheaven</title>
    <id>https://alexleighton.com/posts/2026-07-09-listening-to-superheaven.html</id>
    <link href="https://alexleighton.com/posts/2026-07-09-listening-to-superheaven.html" />
    <published>2026-07-09T14:45:00Z</published>
    <updated>2026-07-09T14:45:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>By Superheaven</p><p>Published on <span title="2026-07-09T14:45:00Z">2026-07-09</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>By Superheaven</h3><p>Published on <span title="2026-07-09T14:45:00Z">2026-07-09</span><br>Tags: listening-to, music</p><a href="https://superheavenband.bandcamp.com/album/superheaven">Superheaven by Superheaven</a>
<p>Grungey, shoegazey rock.</p><p><a href="https://alexleighton.com/posts/2026-07-09-listening-to-superheaven.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>No Docs: macOS-only Packages on OCaml.org</title>
    <id>https://alexleighton.com/posts/2026-07-09-no-docs-macos-only-packages-on-ocaml-org.html</id>
    <link href="https://alexleighton.com/posts/2026-07-09-no-docs-macos-only-packages-on-ocaml-org.html" />
    <published>2026-07-09T14:30:00Z</published>
    <updated>2026-07-09T14:30:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Publishing documentation for osx-keychain.</p><p>Published on <span title="2026-07-09T14:30:00Z">2026-07-09</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Publishing documentation for osx-keychain.</h3><p>Published on <span title="2026-07-09T14:30:00Z">2026-07-09</span><br>Tags: article, documentation, macos, ocaml, software-eng</p><p><strong>The OCaml.org opam documentation process does not trigger for macOS-only packages, leaving ones like <code>osx-keychain</code> labeled as "⚠️ No Docs".</strong></p>
<h2 id="️-no-docs">⚠️ No Docs <a class="heading-anchor" href="#️-no-docs" aria-hidden="true">#</a></h2>
<p>I couldn't find a mention of this in the official documentation. In 2022, <a href="https://discuss.ocaml.org/t/v3-ocaml-org-we-are-live/9747">OCaml.org started serving automatically generated documentation</a> for applicable opam packages, making use of a new <a href="https://icfp21.sigplan.org/details/ocaml-2021-papers/15/A-Multiverse-of-Glorious-Documentation"><code>ocaml-docs-ci</code> documentation pipeline</a>. Earlier this year, <a href="https://tarides.com/blog/2026-01-29-ocaml-org-now-uses-odoc-3-what-s-new/">OCaml.org upgraded to odoc 3</a>, accompanied by <a href="https://jon.recoil.org/blog/2025/04/ocaml-docs-ci-and-odoc-3.html">updates to <code>ocaml-docs-ci</code></a> for odoc 3 compatibility.</p>
<p><a href="https://github.com/ocurrent/ocaml-docs-ci"><code>ocaml-docs-ci</code></a> explicitly targets <a href="https://github.com/ocurrent/ocaml-docs-ci/blob/main/src/lib/platform.ml#L9-L16">Linux platforms</a> only. Because <code>osx-keychain</code> declares <a href="https://github.com/alexleighton/osx-keychain/blob/main/osx-keychain.opam#L41"><code>available: [ os = "macos" ]</code></a>, opam treats it as unavailable on ocaml-docs-ci's Linux workers, filtering it out of the set of packages docs-ci considers buildable before even attempting a build.</p><p>...<br><a href="https://alexleighton.com/posts/2026-07-09-no-docs-macos-only-packages-on-ocaml-org.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Listening To: Nineteen + Memory Tape</title>
    <id>https://alexleighton.com/posts/2026-07-05-listening-to-nineteen-memory-tape.html</id>
    <link href="https://alexleighton.com/posts/2026-07-05-listening-to-nineteen-memory-tape.html" />
    <published>2026-07-06T03:45:00Z</published>
    <updated>2026-07-06T03:45:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>By Desired</p><p>Published on <span title="2026-07-06T03:45:00Z">2026-07-06</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>By Desired</h3><p>Published on <span title="2026-07-06T03:45:00Z">2026-07-06</span><br>Tags: listening-to, music</p><a href="https://neoncityrecords.bandcamp.com/album/nineteen-memory-tape">Nineteen + Memory Tape by Desired</a>
<p>Lofi hiphop, very chill. I love the Sailormoon album cover.</p><p><a href="https://alexleighton.com/posts/2026-07-05-listening-to-nineteen-memory-tape.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Discipline and Agents</title>
    <id>https://alexleighton.com/posts/2026-07-05-discipline-and-agents.html</id>
    <link href="https://alexleighton.com/posts/2026-07-05-discipline-and-agents.html" />
    <published>2026-07-06T03:30:00Z</published>
    <updated>2026-07-06T03:30:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Regaining rigor as agents reshape how we build software.</p><p>Published on <span title="2026-07-06T03:30:00Z">2026-07-06</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Regaining rigor as agents reshape how we build software.</h3><p>Published on <span title="2026-07-06T03:30:00Z">2026-07-06</span><br>Tags: code-review, commentary, llm, quote, software-eng, software-eng-auto</p><blockquote>
<p><a href="https://aicoding.leaflet.pub/3mbrvhyye4k2e"><strong>Chad Fowler</strong> on 2026-01-06</a>:</p><p>XP compressed feedback loops until truth became unavoidable. Tests replaced promises. Continuous integration replaced status reports. Working software replaced narrative. You could no longer hide behind process because the system itself reported your progress, loudly and continuously.</p>
<p>The practices that looked like chaos were actually mechanisms for enforcing honesty. Pair programming meant every line of code had a witness. Test-first meant you couldn't ship wishes. Short iterations meant you couldn't hide. The discipline was more demanding than what came before, not less. It just didn't look like the discipline people were used to seeing.</p></blockquote>
<p>I really enjoyed this article. The first paragraph spoke to my initial experiences with Agile and Pair Programming, though I was second-generation, learning from folks who had worked with Ward Cunningham and Ron Jeffries. The mentions of chaos and shifting of discipline immediately pinged my coding agent radar, so I was delighted to see the article turn that direction at the end of the intro.</p><p>...<br><a href="https://alexleighton.com/posts/2026-07-05-discipline-and-agents.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>TIL: Wikipedia Architecture Statements</title>
    <id>https://alexleighton.com/posts/2026-07-05-til-wikipedia-architecture-statements.html</id>
    <link href="https://alexleighton.com/posts/2026-07-05-til-wikipedia-architecture-statements.html" />
    <published>2026-07-05T22:30:00Z</published>
    <updated>2026-07-05T22:30:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>A field guide to the "laws" of computing.</p><p>Published on <span title="2026-07-05T22:30:00Z">2026-07-05</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>A field guide to the "laws" of computing.</h3><p>Published on <span title="2026-07-05T22:30:00Z">2026-07-05</span><br>Tags: hardware, software-eng, til</p><p>Wikipedia apparently has a 31-entry category, dedicated to the <a href="https://en.wikipedia.org/wiki/Category:Computer_architecture_statements">computer architecture "laws"</a> (statements/conjectures/principles) people have coined. Inside I found <a href="https://en.wikipedia.org/wiki/Haitz%27s_law">Haitz's Law</a>, the LED counterpart to <a href="https://en.wikipedia.org/wiki/Moore's_law">Moore's Law</a>: "every decade, the cost per lumen (unit of useful light emitted) falls by a factor of 10, and the amount of light generated per LED package increases by a factor of 20, for a given wavelength (color) of light."</p><p><a href="https://alexleighton.com/posts/2026-07-05-til-wikipedia-architecture-statements.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Listening To: If the Door Closes</title>
    <id>https://alexleighton.com/posts/2026-07-04-listening-to-if-the-door-closes.html</id>
    <link href="https://alexleighton.com/posts/2026-07-04-listening-to-if-the-door-closes.html" />
    <published>2026-07-04T22:30:00Z</published>
    <updated>2026-07-04T22:30:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>By LANNDS</p><p>Published on <span title="2026-07-04T22:30:00Z">2026-07-04</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>By LANNDS</h3><p>Published on <span title="2026-07-04T22:30:00Z">2026-07-04</span><br>Tags: listening-to, music</p><a href="https://lannds.bandcamp.com/album/if-the-door-closes">If the Door Closes by LANNDS</a>
<p>Their music always reminds me of summer, especially the way Rania Woodard sings.</p><p><a href="https://alexleighton.com/posts/2026-07-04-listening-to-if-the-door-closes.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>osx-keychain Released on Opam</title>
    <id>https://alexleighton.com/posts/2026-07-04-osx-keychain-on-opam.html</id>
    <link href="https://alexleighton.com/posts/2026-07-04-osx-keychain-on-opam.html" />
    <published>2026-07-04T22:00:00Z</published>
    <updated>2026-07-04T22:00:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>My first Opam-published package, and why I built it.</p><p>Published on <span title="2026-07-04T22:00:00Z">2026-07-04</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>My first Opam-published package, and why I built it.</h3><p>Published on <span title="2026-07-04T22:00:00Z">2026-07-04</span><br>Tags: article, macos, ocaml, security, software-eng, static-site</p><p>The <a href="../../../projects/osx-keychain.html"><code>osx-keychain</code></a> library I built to natively pull credentials from the macOS keychain was accepted into Opam and is now publicly available as a dependency, a first for me 🥳. Here is some context on why I made it:</p>
<p>There are two modes in which I interact with AWS for the alexleighton.com static site: during site upload, and during image upload.</p>
<h2 id="site-upload">Site Upload <a class="heading-anchor" href="#site-upload" aria-hidden="true">#</a></h2>
<p>I used to rely on GitHub Actions to build and deploy all commits on the <code>main</code> branch, but it ended up being the worst of all worlds. Reinstalling opam, dune, the OCaml compiler, and all dependencies often took over 10 minutes, regardless of the Actions-caching I tried to apply. My static site is a private repository, so GitHub eventually started nagging about reaching the 1000 monthly build hours threshold for private repos. As a result I turned off the automation and have been building/uploading my site straight off my laptop using a bash script that does what the Action did.</p><p>...<br><a href="https://alexleighton.com/posts/2026-07-04-osx-keychain-on-opam.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Listening To: Skate Story: Vol. 1</title>
    <id>https://alexleighton.com/posts/2026-06-30-listening-to-skate-story-vol-1.html</id>
    <link href="https://alexleighton.com/posts/2026-06-30-listening-to-skate-story-vol-1.html" />
    <published>2026-07-01T05:15:00Z</published>
    <updated>2026-07-01T05:15:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>By Blood Cultures</p><p>Published on <span title="2026-07-01T05:15:00Z">2026-07-01</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>By Blood Cultures</h3><p>Published on <span title="2026-07-01T05:15:00Z">2026-07-01</span><br>Tags: listening-to, music</p><a href="https://bloodcultures.bandcamp.com/album/skate-story-vol-1">Skate Story: Vol. 1 by Blood Cultures</a>
<p>Psychedelic synthwave. The Emptylands track is powerful; wear headphones.</p><p><a href="https://alexleighton.com/posts/2026-06-30-listening-to-skate-story-vol-1.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Changelog: Images from a CDN</title>
    <id>https://alexleighton.com/posts/2026-06-30-changelog-cdn-images.html</id>
    <link href="https://alexleighton.com/posts/2026-06-30-changelog-cdn-images.html" />
    <published>2026-07-01T05:00:00Z</published>
    <updated>2026-07-01T05:00:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Shrinking deployment size 97% by serving images from CloudFront.</p><p>Published on <span title="2026-07-01T05:00:00Z">2026-07-01</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Shrinking deployment size 97% by serving images from CloudFront.</h3><p>Published on <span title="2026-07-01T05:00:00Z">2026-07-01</span><br>Tags: changelog, ocaml, static-site</p><p>Image variants are now served from a CDN at <code>img.alexleighton.com</code> instead of being bundled into the site and served by Amplify.</p>
<p>It seems I <a href="../../../posts/2025-09-23-changelog-images.html">never came back</a> to detail the custom image system underlying the images on this static site, so let's begin with the before, to motivate the after. The image system comprises a private S3 bucket, local filesystem cache, image "database", and an image system library.</p>
<p>The image system library is written in OCaml and integrated into the static site generator, to allow image reference resolution. A separate executable fronts the image system, to allow uploading and syncing of images during post authoring. Image upload through the system generates a number of variants of different sizes and formats (<code>jpeg</code> as the lowest common denominator, <code>webp</code> for most browsers, <code>avif</code> for modern browsers), assigns a <a href="../../../posts/2025-11-29-typeids-for-knowledge-bases.html">TypeId</a> to each image, uploads the images to the source-of-truth private S3 bucket, adds them to the filesystem cache, and adds corresponding rows to the CSV image database. The site generator reads the image database to dereference image TypeIds into source URLs, copies every referenced image into the output directory, and includes those images in the release artifact.</p><p>...<br><a href="https://alexleighton.com/posts/2026-06-30-changelog-cdn-images.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Houses Under a Mackerel Sky</title>
    <id>https://alexleighton.com/posts/2026-06-28-houses-under-a-mackerel-sky.html</id>
    <link href="https://alexleighton.com/posts/2026-06-28-houses-under-a-mackerel-sky.html" />
    <published>2026-06-29T00:00:00Z</published>
    <updated>2026-06-29T00:00:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Upwards and outwards.</p><p>Published on <span title="2026-06-29T00:00:00Z">2026-06-29</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Upwards and outwards.</h3><p>Published on <span title="2026-06-29T00:00:00Z">2026-06-29</span><br>Tags: photography, seattle</p><p><a href="../../../img/img_o_01kw8a36fgf4vb9jd7fr5rvrq1.html"><img src="https://img.alexleighton.com/img_01kw8a37erf3rtsdpd6jkbv8t0.jpg" alt="An octagonal corner tower of a Queen Anne house, topped with a conical wood-shingle roof. The tower has slate-blue shingle siding, cream trim, and white-framed windows catching low golden sunlight. Leafy green branches frame the foreground against a blue sky streaked with thin clouds."></img></a></p>
<p><a href="../../../img/img_o_01kw8a40v8fmm9jxfy0xnfzyha.html"><img src="https://img.alexleighton.com/img_01kw8a41tgeqvvtzg9s5bb1b5d.jpg" alt="A rose-red Victorian house with a steep front gable and an arched attic window, partly screened by tall trees. Evening sun dapples the shingled facade. Stone steps climb through dense green hedges toward a covered porch, beneath a clear blue sky."></img></a></p>
<p><a href="../../../img/img_o_01kw8a4dhgf9ebz40pcdzrvymc.html"><img src="https://img.alexleighton.com/img_01kw8a4egre8ct4c1ptbwp69j3.jpg" alt="A wide &quot;mackerel sky&quot; of rippled, dappled altocumulus clouds fading from white into blue. Along the bottom edge, the silhouettes of evergreen treetops and a boxy building stand in shadow."></img></a></p><p><a href="https://alexleighton.com/posts/2026-06-28-houses-under-a-mackerel-sky.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Changelog: Listening Page</title>
    <id>https://alexleighton.com/posts/2026-06-27-changelog-listening-page.html</id>
    <link href="https://alexleighton.com/posts/2026-06-27-changelog-listening-page.html" />
    <published>2026-06-27T23:20:00Z</published>
    <updated>2026-06-27T23:20:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>A feed of the music I've been listening to.</p><p>Published on <span title="2026-06-27T23:20:00Z">2026-06-27</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>A feed of the music I've been listening to.</h3><p>Published on <span title="2026-06-27T23:20:00Z">2026-06-27</span><br>Tags: changelog, static-site</p><p>There's now a <a href="../../../listening.html">Listening</a> page: a feed of every <a href="../../../posts/tags/listening-to.html">listening-to</a>-tagged post, showing the track title, artists, my commentery, and a link to play it.</p>
<p>Like the <a href="../../../photos.html">Photos</a> page, the feed is assembled entirely from existing template builtins — <code>setlist</code> to gather the tagged posts and <code>foreach</code> to render each row — reading from a <code>music</code> frontmatter:</p>
<pre><code class="language-yaml">---
...
music:
  artist: [Ninajirachi]
  title: I Love My Computer
  kind: album
  source: bandcamp
  url: https://ninajirachi.bandcamp.com/album/i-love-my-computer
  commentary: |-
    A love letter to computers and video game sounds in the best way.
---
</code></pre><p><a href="https://alexleighton.com/posts/2026-06-27-changelog-listening-page.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Listening To: Contorted</title>
    <id>https://alexleighton.com/posts/2026-06-20-listening-to-contorted.html</id>
    <link href="https://alexleighton.com/posts/2026-06-20-listening-to-contorted.html" />
    <published>2026-06-20T22:10:00Z</published>
    <updated>2026-06-20T22:10:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>By REZZ</p><p>Published on <span title="2026-06-20T22:10:00Z">2026-06-20</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>By REZZ</h3><p>Published on <span title="2026-06-20T22:10:00Z">2026-06-20</span><br>Tags: listening-to, music</p><a href="https://www.youtube.com/watch?v=Ot4epbF9Mek">REZZ - Contorted</a>
<p>Edgy, thumping bass.</p><p><a href="https://alexleighton.com/posts/2026-06-20-listening-to-contorted.html">Read the post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Java&#39;s Project Valhalla</title>
    <id>https://alexleighton.com/posts/2026-06-20-javas-project-valhalla.html</id>
    <link href="https://alexleighton.com/posts/2026-06-20-javas-project-valhalla.html" />
    <published>2026-06-20T22:00:00Z</published>
    <updated>2026-06-20T22:00:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>A decade of work arrives in JDK 28</p><p>Published on <span title="2026-06-20T22:00:00Z">2026-06-20</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>A decade of work arrives in JDK 28</h3><p>Published on <span title="2026-06-20T22:00:00Z">2026-06-20</span><br>Tags: commentary, java, kotlin, quote, software-eng</p><p>Wonderfully in-depth article on the history and technical details of "value objects" arriving in JDK 28. Very much worth a read.</p>
<blockquote>
<p><a href="https://www.jvm-weekly.com/p/project-valhalla-explained-how-a"><strong>Artur Skowronski</strong> on 2026-06-18</a>:</p><p>On June 15, Oracle engineer Lois Foltan <a href="https://mail.openjdk.org/archives/list/jdk-dev@openjdk.org/message/AIA3O3LHFZ6T7TIPH7KZT4WS4B6U72U5/">confirmed</a> what a good chunk of the industry had stopped believing: <a href="https://openjdk.org/jeps/401">JEP 401: Value Classes and Objects</a> will be integrated into the main OpenJDK repository and is targeting JDK 28.</p>
<p>...</p>
<p>Why do I call this one of the biggest changes in the platform’s history? Because Valhalla doesn’t bolt yet another feature onto the language; it moves its deepest assumption. “Every object has identity” had been true in Java since 1995; it’s the foundation everything else stood on. Letting the programmer opt out of that assumption (choose which objects need identity and which don’t) isn’t a refactor, it’s a shift of the foundation. And that’s exactly why it unlocks a whole decade of further work: unifying primitives and objects, specializing generics, denser collections, faster numerics.</p></blockquote><p>...<br><a href="https://alexleighton.com/posts/2026-06-20-javas-project-valhalla.html">Read the full post →</a></p>]]></content>
  </entry>
  
  <entry>
    <title>Context Anxiety</title>
    <id>https://alexleighton.com/posts/2026-06-20-context-anxiety.html</id>
    <link href="https://alexleighton.com/posts/2026-06-20-context-anxiety.html" />
    <published>2026-06-20T21:00:00Z</published>
    <updated>2026-06-20T21:00:00Z</updated>
    <author><name>Alex Leighton</name></author>
    <summary type="html"><![CDATA[<p>Knowing your limits can lead to quitting early.</p><p>Published on <span title="2026-06-20T21:00:00Z">2026-06-20</span></p>]]></summary>
    <content type="html"><![CDATA[<h3>Knowing your limits can lead to quitting early.</h3><p>Published on <span title="2026-06-20T21:00:00Z">2026-06-20</span><br>Tags: commentary, llm, software-eng-auto</p><p>I mentioned the following finding to a friend recently but hadn't posted about it here, so rectifying that.</p>
<blockquote>
<p><a href="https://cognition.com/blog/devin-sonnet-4-5-lessons-and-challenges"><strong>Cognition Team</strong> on 2025-09-29</a>:</p><p>Sonnet 4.5 is the first model we've seen that is aware of its own context window, and this shapes how it behaves. As it approaches context limits, we've observed it proactively summarizing its progress and becoming more decisive about implementing fixes to close out tasks.</p>
<p>This "context anxiety" can actually hurt performance: we found the model taking shortcuts or leaving tasks incomplete when it believed it was near the end of its window, even when it had plenty of room left.</p></blockquote><p>...<br><a href="https://alexleighton.com/posts/2026-06-20-context-anxiety.html">Read the full post →</a></p>]]></content>
  </entry>
  
</feed>