<?xml version="1.0" encoding="UTF-8" ?> <?xml-stylesheet type="text/xsl" href="rss.xsl"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"> <channel> <title>Hypertext Dispatches</title><description>Hypertext Dispatches by Ryan Johnson</description><link>https://tenthirtyam.org/</link><atom:link href="https://tenthirtyam.org/rss.xml" rel="self" type="application/rss+xml" /> <managingEditor>Ryan Johnson</managingEditor><language>en</language> <pubDate>Wed, 05 Aug 2026 19:19:47 -0000</pubDate> <lastBuildDate>Wed, 05 Aug 2026 19:19:47 -0000</lastBuildDate> <ttl>1440</ttl> <generator>MkDocs RSS plugin - v1.19.0</generator> <image> <url>None</url> <title>Hypertext Dispatches</title> <link>https://tenthirtyam.org/</link> </image> <item> <title>Announcing the Packer Plugin for Artifactory</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Automation</category> <category>Developer Workflow</category> <category>Documentation</category> <category>HashiCorp Packer</category> <category>Infrastructure-as-Code</category> <category>Open Source</category> <category>Technology</category> <description>&lt;p&gt;Today marks the &lt;a href=&#34;https://github.com/tenthirtyam/packer-plugin-artifactory/releases/tag/v0.1.0&#34;&gt;v0.1.0&lt;/a&gt; release of the &lt;a href=&#34;https://github.com/tenthirtyam/packer-plugin-artifactory&#34;&gt;Packer Plugin for Artifactory&lt;/a&gt;, my first standalone Packer plugin. This one&#39;s been on the list for a while.&lt;/p&gt; &lt;p&gt;The plugin adds an &lt;code&gt;artifactory&lt;/code&gt; post-processor. After a Packer build produces an OVA or OVF, the post-processor uploads it straight to JFrog Artifactory. Build, export, upload, done. No handoff step, no separate script, no copy-pasting artifact paths into another job.&lt;/p&gt; &lt;p&gt;Primary targets are the &lt;code&gt;vmware/vsphere&lt;/code&gt; and &lt;code&gt;vmware/vmware&lt;/code&gt; Packer plugins, covering vSphere, Fusion, and Workstation. Any other builder that emits OVA or OVF should work too. Authentication supports username and password, API key, and access token. Custom properties let teams attach version, OS, and build metadata right from the post-processor block.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/08/04/announcing-the-packer-plugin-for-artifactory/</link> <pubDate>Tue, 04 Aug 2026 00:00:01 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/08/04/announcing-the-packer-plugin-for-artifactory/</guid> </item> <item> <title>Announcing the Packer Plugin for VMware vSphere v2.3.0</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Automation</category> <category>HashiCorp Packer</category> <category>Infrastructure-as-Code</category> <category>Technology</category> <category>VMware vSphere</category> <description>&lt;p&gt;Packer Plugin for VMware vSphere &lt;a href=&#34;https://github.com/vmware/packer-plugin-vsphere/releases/tag/v2.3.0&#34;&gt;v2.3.0&lt;/a&gt; was released on 03 August 2026!&lt;/p&gt; &lt;p&gt;This release expands how &lt;code&gt;vsphere-clone&lt;/code&gt; starts a build. Inventory templates still work. So do content library items, and local or remote OVF/OVA packages. Remote sources support HTTP, HTTPS, and HTTPS with basic authentication. Pick the source that matches where the image already lives, then customize, provision, and publish as usual.&lt;/p&gt; &lt;p&gt;v2.3.0 also expands vSphere data sources for inventory lookups in HCL, ships project documentation at &lt;a href=&#34;https://vmware.github.io/packer-plugin-vsphere&#34;&gt;vmware.github.io/packer-plugin-vsphere&lt;/a&gt;, and includes reliability improvements, clearer validation, broader test coverage, and dependency updates.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/08/04/announcing-the-packer-plugin-for-vmware-vsphere-v230/</link> <pubDate>Tue, 04 Aug 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/08/04/announcing-the-packer-plugin-for-vmware-vsphere-v230/</guid> </item> <item> <title>Oh, Adeline</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>39 North</category> <category>Americana</category> <category>Country</category> <category>Music</category> <category>Songwriting</category> <category>Songwriting</category> <category>Southern Gothic</category> <description>&lt;p&gt;An original murder ballad, inspired by the traditional folk songs &lt;em&gt;“Poor Ellen Smith”&lt;/em&gt; and &lt;em&gt;“Two Sisters”&lt;/em&gt;&lt;/p&gt; &lt;p&gt;!!! warning &#34;Trigger Warning&#34; This piece incl...&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/08/02/oh-adeline/</link> <pubDate>Sun, 02 Aug 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/08/02/oh-adeline/</guid> </item> <item> <title>For It All</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>39 North</category> <category>Country</category> <category>Music</category> <category>Songwriting</category> <category>Songwriting</category> <description>&lt;p&gt;!!! lyrics &#34;Lyrics&#34;&lt;/p&gt; &lt;pre&gt;&lt;code&gt;**For It All** The radiator’s humming The lights are turned down low I’m leaning on the counter Watching head... &lt;/code&gt;&lt;/pre&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/08/01/for-it-all/</link> <pubDate>Sat, 01 Aug 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/08/01/for-it-all/</guid> </item> <item> <title>How to Structure an Ansible Collection</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Ansible</category> <category>Ansible Collections</category> <category>Automation</category> <category>DevOps</category> <category>Developer Workflow</category> <category>Infrastructure-as-Code</category> <category>Technology</category> <description>&lt;p&gt;&lt;img alt=&#34;Ansible&#34; src=&#34;../images/post-ansible-logo.svg&#34;&gt;{ align=right width=150 .skip-lightbox }&lt;/p&gt; &lt;p&gt;I recently wrapped up work on an Ansible collection I developed for a customer through my role at Broadcom. With the project complete, I wanted to write down the structure it followed and the reasons behind it. This guide is for developers building their first collection and maintainers checking an existing one against Ansible&#39;s recommended practices.&lt;/p&gt; &lt;p&gt;Those decisions matter once an Ansible repository has been in use for a while. Roles sit beside playbooks that depend on custom filters. Lookup plugins get copied from one repository to another. The same automation has to run locally and in Ansible Automation Platform (AAP), where repository-specific plugin paths become difficult to maintain.&lt;/p&gt; &lt;p&gt;A collection gives that content a package name and a standard layout. Roles, plugins, playbooks, documentation, and tests can ship together as a versioned package under a namespace such as &lt;code&gt;example.platform&lt;/code&gt;. Once you understand where each part belongs, the structure is straightforward.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/07/21/how-to-structure-an-ansible-collection/</link> <pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/07/21/how-to-structure-an-ansible-collection/</guid> </item> <item> <title>Farmer&#39;s Daughter</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>39 North</category> <category>Country</category> <category>Music</category> <category>Songwriting</category> <category>Songwriting</category> <description>&lt;p&gt;!!! note &#34;Reflection&#34; Published alongside &lt;a href=&#34;2026-07-02-field-after-field-song-after-song.md&#34;&gt;Field After Field, Song After Song&lt;/a&gt;, a reflection on the ...&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/07/02/farmers-daughter/</link> <pubDate>Thu, 02 Jul 2026 00:00:01 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/07/02/farmers-daughter/</guid> </item> <item> <title>Field After Field, Song After Song</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Personal</category> <category>Writing</category> <description>&lt;p&gt;90s country music takes me back to Saturday mornings in Southwest Georgia, when my dad, my brother, and I would climb into an old two-toned orange and white ...&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/07/02/field-after-field-song-after-song/</link> <pubDate>Thu, 02 Jul 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/07/02/field-after-field-song-after-song/</guid> </item> <item> <title>Development Containers: Consistent Environments for Every Contributor</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Automation</category> <category>Developer Experience</category> <category>Developer Tools</category> <category>Developer Workflow</category> <category>Docker</category> <category>GitHub Codespaces</category> <category>Infrastructure-as-Code</category> <category>Open Source</category> <category>Technology</category> <description>&lt;p&gt;&lt;img alt=&#34;Development Containers logo&#34; src=&#34;../images/post-development-containers.png&#34;&gt;{ align=right width=&#34;200&#34; .skip-lightbox }&lt;/p&gt; &lt;p&gt;Some engineering teams hit the same friction eventually: A new developer clones the repository, follows the setup instructions, and spends the next two hours debugging why the toolchain that works on everyone else&#39;s machine doesn&#39;t work on theirs. The versions are slightly different. A system dependency is missing. The environment variable was never set. By the time they make their first commit, they&#39;ve already burned half a day on tasks that had nothing to do with the code they were hired to write.&lt;/p&gt; &lt;p&gt;Development containers help solve this by codifying the development environment as a container image. Every contributor uses the same tools at the same versions on every machine. Onboarding becomes more a matter of opening the repository rather than following a tedious setup guide.&lt;/p&gt; &lt;p&gt;A development container, commonly called a &lt;em&gt;&#34;devcontainer&#34;&lt;/em&gt;, is a Docker container configured as a development environment. It holds the runtime, tools, extensions, and settings required to work on the project, and that configuration lives in the repository right next to the codebase.&lt;/p&gt; &lt;p&gt;The &lt;a href=&#34;https://containers.dev&#34;&gt;Development Containers specification&lt;/a&gt; defines the format that editor and platform integrations follow. VS Code, GitHub Codespaces, JetBrains Gateway, and the Dev Containers CLI all consume the same &lt;code&gt;.devcontainer/&lt;/code&gt; definition. A valid configuration should work across those entry points without forked setup docs.&lt;/p&gt; &lt;p&gt;Instead of a &lt;code&gt;README.md&lt;/code&gt; that says &lt;em&gt;&#34;install &lt;code&gt;x&lt;/code&gt; v1.24, &lt;code&gt;y&lt;/code&gt; 1.11, and &lt;code&gt;z&lt;/code&gt; v7.1.2,&#34;&lt;/em&gt; the repository includes a container image specification.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/07/01/development-containers-consistent-environments-for-every-contributor/</link> <pubDate>Wed, 01 Jul 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/07/01/development-containers-consistent-environments-for-every-contributor/</guid> </item> <item> <title>MCP Servers: A Practical Guide to Context on Demand</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>AI</category> <category>Automation</category> <category>Developer Tools</category> <category>Developer Workflow</category> <category>Model Context Protocol</category> <category>Technology</category> <description>&lt;p&gt;Model Context Protocol, or MCP, is how an AI client asks for context instead of waiting for you to shuttle it in. Clients can already expose open files, workspace context, and sometimes terminal output. Remote services, databases, CI runs, output from another shell, you still feed that in by hand. MCP gives the client a shared protocol to discover tools, read resources, and reach those systems directly. If the LLM is doing the reasoning, an MCP server is the part that lets it look around and, when you allow it, act on current state.&lt;/p&gt; &lt;p&gt;The model doesn&#39;t have to rely only on whatever you remembered to supply it. It can ask for current state, call a tool you exposed, and come back with something closer to evidence.&lt;/p&gt; &lt;p&gt;Less autocomplete. Less guessing. More &lt;em&gt;&#34;I checked x and y, and here is what I found.&#34;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;MCP is an open protocol for connecting AI applications to the systems around them.&lt;/p&gt; &lt;p&gt;An MCP server can expose a few kinds of things:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Tools&lt;/strong&gt;: actions the model can ask to run, such as &lt;code&gt;read_logs&lt;/code&gt;, &lt;code&gt;run_tests&lt;/code&gt;, or a query you wrapped instead of exposing raw shell.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Resources&lt;/strong&gt;: readable context, such as repository metadata, service health, runbooks, or log files.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Prompts&lt;/strong&gt;: reusable prompt templates that package common workflows.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;An MCP client, such as VS Code or Cursor, connects to one or more servers and surfaces those capabilities to the model.&lt;/p&gt; &lt;p&gt;| Old Workflow | MCP Workflow | |-------------------------------|---------------------------------------------------| | Paste a log into a chat | The model calls a &lt;code&gt;read_logs&lt;/code&gt; tool | | Explain your repository | The client provides workspace context | | Paste command output | The server returns structured tool output | | Ask the model to guess state | The model asks the system for current state | | Manually perform every action | The model proposes or invokes approved tool calls |&lt;/p&gt; &lt;p&gt;MCP doesn&#39;t make a model omniscient. It gives the model a way to ask for context and use the actions you chose to expose. That matters more once you&#39;ve lived through the manual context loop a few dozen times.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/26/mcp-servers-a-practical-guide-to-context-on-demand/</link> <pubDate>Fri, 26 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/26/mcp-servers-a-practical-guide-to-context-on-demand/</guid> </item> <item> <title>I&#39;ll Be Damned</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>39 North</category> <category>Americana</category> <category>Country</category> <category>Music</category> <category>Songwriting</category> <category>Songwriting</category> <description>&lt;p&gt;!!! note &#34;Reflection&#34;&lt;/p&gt; &lt;pre&gt;&lt;code&gt;Some roads don&#39;t take you anywhere new; the ones that drag you back to what you can&#39;t forget. For me, that’s the haunted str... &lt;/code&gt;&lt;/pre&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/22/ill-be-damned/</link> <pubDate>Mon, 22 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/22/ill-be-damned/</guid> </item> <item> <title>Generating a Python SDK from an OpenAPI Specification</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Developer Tools</category> <category>Developer Workflow</category> <category>Open Source</category> <category>OpenAPI</category> <category>Python</category> <category>SDK</category> <category>Technology</category> <description>&lt;p&gt;If your API ships an OpenAPI spec, &lt;a href=&#34;https://openapi-generator.tech&#34;&gt;OpenAPI Generator&lt;/a&gt; can build the Python client from it. You don&#39;t have to hand-write mode...&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/21/generating-a-python-sdk-from-an-openapi-specification/</link> <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/21/generating-a-python-sdk-from-an-openapi-specification/</guid> </item> <item> <title>Making Sense of the Circle of Fifths</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Circle of Fifths</category> <category>Guitar</category> <category>Music</category> <category>Music Theory</category> <description>&lt;p&gt;If the &lt;strong&gt;Circle of Fifths&lt;/strong&gt; has always looked like one of those theory diagrams everyone swears is important but no one actually explains, you&#39;re not alone. The good news is that it&#39;s not really a chart about memorizing symbols. It&#39;s a map of how keys, chords, and musical motion relate to each other, and once you hear that on guitar, it starts feeling useful fast.&lt;/p&gt; &lt;p&gt;For a lot of players, the Circle of Fifths feels abstract because it gets introduced on paper instead of on the fretboard.&lt;/p&gt; &lt;p&gt;If my &lt;a href=&#34;2026-06-14-major-and-minor-pentatonic-scales.md&#34;&gt;Decoding the Major and Minor Pentatonic Scales&lt;/a&gt; post was about understanding what&#39;s happening inside the pentatonic scale shapes, this one is about understanding why chords and keys pull the way they do around those scale shapes.&lt;/p&gt; &lt;p&gt;My goal here is to help you:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;understand what the circle is actually showing you,&lt;/li&gt; &lt;li&gt;learn why moving by &lt;strong&gt;fifths&lt;/strong&gt; sounds so strong in music,&lt;/li&gt; &lt;li&gt;connect nearby keys to nearby chord families, and&lt;/li&gt; &lt;li&gt;use the circle for progressions, songwriting, and practice.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;!!! tip The Circle of Fifths isn&#39;t mainly about memorizing key signatures. It&#39;s about seeing which keys are closely related, which chords want to lead to each other, and why certain progressions feel so natural.&lt;/p&gt; &lt;h2&gt;What Is the Circle of Fifths?&lt;/h2&gt; &lt;p&gt;At its core, the &lt;strong&gt;Circle of Fifths&lt;/strong&gt; is just an ordered list of notes.&lt;/p&gt; &lt;p&gt;Start on &lt;code&gt;C&lt;/code&gt;. Move up a &lt;strong&gt;perfect fifth&lt;/strong&gt; and you get &lt;code&gt;G&lt;/code&gt;. Move up another fifth and you get &lt;code&gt;D&lt;/code&gt;.&lt;/p&gt; &lt;p&gt;Keep going and you get:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;C&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;G&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;D&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;A&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;E&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;B&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;F#&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Db&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Ab&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Eb&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;Bb&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;F&lt;/code&gt;&lt;/li&gt; &lt;li&gt;back to &lt;code&gt;C&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;That&#39;s the circle.&lt;/p&gt; &lt;p&gt;If you move the other direction, you&#39;re moving by &lt;strong&gt;fourths&lt;/strong&gt;, which lands on the same set of keys in reverse order.&lt;/p&gt; &lt;p&gt;&lt;em&gt;&#34;Why does that matter?&#34;&lt;/em&gt;&lt;/p&gt; &lt;p&gt;Because music built from neighboring keys tends to share a lot of notes and chords. The closer two keys are on the circle, the more naturally they tend to connect.&lt;/p&gt; &lt;p&gt;&lt;img alt=&#34;Circle of Fifths&#34; src=&#34;../images/post-circle-of-fifths-wheel-dark.svg#only-dark&#34;&gt;{ width=&#34;720&#34; .skip-lightbox } &lt;img alt=&#34;Circle of Fifths&#34; src=&#34;../images/post-circle-of-fifths-wheel.svg#only-light&#34;&gt;{ width=&#34;720&#34; .skip-lightbox }&lt;/p&gt; &lt;p&gt;!!! note &#34;Guitar Translation&#34; Think of the circle as a map of musical neighborhoods. Keys that sit next to each other are closely related. Keys across the circle feel more distant.&lt;/p&gt; &lt;h2&gt;Why Fifths Sound So Strong&lt;/h2&gt; &lt;p&gt;The interval of a &lt;strong&gt;fifth&lt;/strong&gt; is one of the most stable and powerful sounds in music.&lt;/p&gt; &lt;p&gt;Guitar players already know this sound, even if they don&#39;t call it by name:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A basic power chord is built around the &lt;strong&gt;Root Note&lt;/strong&gt; and the &lt;code&gt;5&lt;/code&gt;.&lt;/li&gt; &lt;li&gt;Power chords put the sound of the fifth under your fingers all over the neck.&lt;/li&gt; &lt;li&gt;A lot of strong chord movement in rock, blues, country, and pop follows fifth relationships!&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;The motion around the circle lines up with one of the most fundamental relationships in the instrument and in tonal music itself.&lt;/p&gt; &lt;p&gt;!!! tip When you hear progressions like &lt;code&gt;D - G - C&lt;/code&gt; or &lt;code&gt;Em - Am - D - G&lt;/code&gt;, you&#39;re hearing the motion that lines up with the circle. And your ear recognizes that pull &lt;em&gt;immediately&lt;/em&gt;.&lt;/p&gt; &lt;h2&gt;Clockwise and Counterclockwise&lt;/h2&gt; &lt;p&gt;One reason the circle matters is that it helps organize keys.&lt;/p&gt; &lt;p&gt;Moving &lt;strong&gt;clockwise&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;goes up by fifths,&lt;/li&gt; &lt;li&gt;adds sharps, and&lt;/li&gt; &lt;li&gt;often feels like increasing harmonic brightness or tension&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Moving &lt;strong&gt;counterclockwise&lt;/strong&gt;:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;goes up by fourths,&lt;/li&gt; &lt;li&gt;adds flats, and&lt;/li&gt; &lt;li&gt;often feels like a move toward warmer, flatter key areas&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Here&#39;s a practical shorthand:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;C&lt;/code&gt; has no sharps and no flats&lt;/li&gt; &lt;li&gt;one step clockwise, &lt;code&gt;G&lt;/code&gt;, has 1 sharp&lt;/li&gt; &lt;li&gt;one more step, &lt;code&gt;D&lt;/code&gt;, has 2 sharps&lt;/li&gt; &lt;li&gt;one step counterclockwise, &lt;code&gt;F&lt;/code&gt;, has 1 flat&lt;/li&gt; &lt;li&gt;one more step, &lt;code&gt;Bb&lt;/code&gt;, has 2 flats&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;!!! note &#34;Stop! You Don&#39;t Need to Memorize All of This at Once!&#34; Start with just &lt;code&gt;C, G, D, A&lt;/code&gt; on the sharp side and &lt;code&gt;C, F, Bb&lt;/code&gt; on the flat side. That small map already explains a huge amount of real guitar music.&lt;/p&gt; &lt;h2&gt;Relative Minor&lt;/h2&gt; &lt;p&gt;The Circle of Fifths isn&#39;t only about major keys. Each major key has a &lt;strong&gt;Relative Minor&lt;/strong&gt; that uses the same notes.&lt;/p&gt; &lt;p&gt;Examples:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;code&gt;C major&lt;/code&gt; and &lt;code&gt;A minor&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;G major&lt;/code&gt; and &lt;code&gt;E minor&lt;/code&gt;&lt;/li&gt; &lt;li&gt;&lt;code&gt;D major&lt;/code&gt; and &lt;code&gt;B minor&lt;/code&gt;&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;If that sounds familiar, it should. It&#39;s the same relationship we used in &lt;a href=&#34;2026-06-14-major-and-minor-pentatonic-scales.md&#34;&gt;Decoding the Major and Minor Pentatonic Scales&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;The circle helps you see those pairs as families:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;major key on the outside&lt;/li&gt; &lt;li&gt;relative minor connected to the same note pool&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;That&#39;s useful when:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;understanding songs that shift between major and minor moods,&lt;/li&gt; &lt;li&gt;finding related scales quickly, and&lt;/li&gt; &lt;li&gt;writing chord progressions that feel connected without feeling repetitive&lt;/li&gt; &lt;/ul&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/20/making-sense-of-the-circle-of-fifths/</link> <pubDate>Sat, 20 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/20/making-sense-of-the-circle-of-fifths/</guid> </item> <item> <title>vmcli: A Practical Guide for the VMware Fusion and Workstation Command Line</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Automation</category> <category>Documentation</category> <category>Technology</category> <category>Terminal</category> <category>VMware Desktop Hypervisors</category> <category>VMware Fusion</category> <category>VMware Workstation</category> <description>&lt;p&gt;The command line is still the fastest way to script power state, disks, snapshots, and guest operations on with &lt;strong&gt;VMware Fusion&lt;/strong&gt; (macOS) and **VMware Workst...&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/19/vmcli-a-practical-guide-for-the-vmware-fusion-and-workstation-command-line/</link> <pubDate>Fri, 19 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/19/vmcli-a-practical-guide-for-the-vmware-fusion-and-workstation-command-line/</guid> </item> <item> <title>Requests vs. HTTPX: Choosing a Python HTTP Client</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Automation</category> <category>Developer Experience</category> <category>Developer Workflow</category> <category>Open Source</category> <category>Python</category> <category>Technology</category> <description>&lt;p&gt;&lt;code&gt;requests&lt;/code&gt; earned its reputation honestly. For a long time, if you needed to call an API, download a file, or glue two services together in Python, &lt;code&gt;requests&lt;/code&gt; was usually the obvious answer.&lt;/p&gt; &lt;p&gt;Async web frameworks, high-concurrency services, and I/O-heavy workloads changed what many teams need from an HTTP client. That&#39;s where &lt;code&gt;httpx&lt;/code&gt; starts to matter.&lt;/p&gt; &lt;p&gt;This post compares &lt;code&gt;requests&lt;/code&gt; and &lt;code&gt;httpx&lt;/code&gt; from the point of view of a Python developer who already knows &lt;code&gt;requests&lt;/code&gt;, wants a clear explanation of what &lt;code&gt;httpx&lt;/code&gt; adds, and doesn&#39;t want hand-wavy &#34;modernization&#34; advice.&lt;/p&gt; &lt;h2&gt;The Champion: &lt;code&gt;requests&lt;/code&gt;&lt;/h2&gt; &lt;p&gt;&lt;code&gt;requests&lt;/code&gt; became the standard because it removed friction. Small API. Sensible defaults. &lt;code&gt;Session&lt;/code&gt; when you need reuse.&lt;/p&gt; &lt;ul&gt; &lt;li&gt;The API is small and easy to learn.&lt;/li&gt; &lt;li&gt;The defaults are simple enough for scripts and internal tools.&lt;/li&gt; &lt;li&gt;&lt;code&gt;Session&lt;/code&gt; gives you connection reuse and shared configuration without much ceremony.&lt;/li&gt; &lt;li&gt;The ecosystem around it is huge: tutorials, examples, blog posts, Stack Overflow answers, and third-party integrations all assume you know &lt;code&gt;requests&lt;/code&gt;.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;For synchronous Python code, it&#39;s still a good library. A lot of production code doesn&#39;t need async support, doesn&#39;t need HTTP/2, and doesn&#39;t need a broader transport model. In those cases, &lt;code&gt;requests&lt;/code&gt; remains a sensible choice.&lt;/p&gt; &lt;p&gt;That&#39;s why this comparison is not really about replacing a bad tool. It&#39;s about recognizing where the older tool stops fitting as cleanly.&lt;/p&gt; &lt;h2&gt;The Challenger: &lt;code&gt;httpx&lt;/code&gt;&lt;/h2&gt; &lt;p&gt;&lt;code&gt;httpx&lt;/code&gt; looks familiar on purpose. The synchronous API feels close enough to &lt;code&gt;requests&lt;/code&gt; that most Python developers can read it immediately. That compatibility is one of its best features, because it lowers the cost of trying it.&lt;/p&gt; &lt;p&gt;Its two biggest advantages are:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Native &lt;code&gt;async&lt;/code&gt; and &lt;code&gt;await&lt;/code&gt; support through &lt;code&gt;httpx.AsyncClient&lt;/code&gt;&lt;/li&gt; &lt;li&gt;Optional HTTP/2 support on both sync and async clients&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Those aren&#39;t cosmetic differences.&lt;/p&gt; &lt;p&gt;Async support means &lt;code&gt;httpx&lt;/code&gt; fits naturally into frameworks like FastAPI, Starlette, and any other async application that should not block the event loop on outbound network calls. HTTP/2 support means one client connection can handle multiplexed requests when the remote server supports it, which can matter for high-concurrency workloads.&lt;/p&gt; &lt;p&gt;You opt in with &lt;code&gt;httpx.Client(http2=True)&lt;/code&gt; or &lt;code&gt;httpx.AsyncClient(http2=True)&lt;/code&gt;, and the server still has to support HTTP/2 for you to get it.&lt;/p&gt; &lt;p&gt;&lt;code&gt;httpx&lt;/code&gt; also pushes users toward safer networking defaults. The biggest example is timeouts: &lt;code&gt;requests&lt;/code&gt; doesn&#39;t time out unless you ask it to, while &lt;code&gt;httpx&lt;/code&gt; enforces timeouts by default.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/18/requests-vs-httpx-choosing-a-python-http-client/</link> <pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/18/requests-vs-httpx-choosing-a-python-http-client/</guid> </item> <item> <title>Decoding the Major and Minor Pentatonic Scales</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Guitar</category> <category>Music</category> <category>Music Theory</category> <category>Pentatonic Scale</category> <description>&lt;p&gt;If you&#39;ve ever felt trapped inside the classic minor pentatonic box, you&#39;re not alone. The good news is that the box isn&#39;t the problem. The real breakthrough comes when you understand what the notes inside that shape are doing, and that&#39;s the moment the fretboard starts making sense.&lt;/p&gt; &lt;p&gt;Most intermediate players start in the same place: &lt;strong&gt;Minor Pentatonic Position 1&lt;/strong&gt;, fingers parked at the 5th fret, trying to find fresh ideas out of the same old lick. While that scale shape is useful, but it can start to feel a bit clostrophobic.&lt;/p&gt; &lt;p&gt;My goal with this post is to help you:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Stop seeing pentatonic scales as random patterns.&lt;/li&gt; &lt;li&gt;Start seeing them as &lt;strong&gt;intervals&lt;/strong&gt;, &lt;strong&gt;Root Notes&lt;/strong&gt;, and musical colors.&lt;/li&gt; &lt;li&gt;Learn why major and minor pentatonic scales are deeply connected.&lt;/li&gt; &lt;li&gt;Use that connection to make better phrases anywhere on the neck of the guitar.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;!!! tip You don&#39;t need to memorize five more disconnected shapes to improve. You need to understand what your current shape is already showing you.&lt;/p&gt; &lt;p&gt;The word &lt;strong&gt;pentatonic&lt;/strong&gt; just means &lt;strong&gt;five notes&lt;/strong&gt;.&lt;/p&gt; &lt;p&gt;That&#39;s the whole idea:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;A major scale has 7 notes.&lt;/li&gt; &lt;li&gt;A natural minor scale has 7 notes.&lt;/li&gt; &lt;li&gt;A pentatonic scale trims that down to 5.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Why remove two notes?&lt;/p&gt; &lt;p&gt;Because the notes that are left out are the ones that create the strongest half-step tension. Whilst half-steps aren&#39;t bad, they&#39;re the notes most likely to sound tense, crunchy, or like they want immediate resolution. When you remove them, the scale becomes smoother and more forgiving.&lt;/p&gt; &lt;p&gt;That&#39;s why pentatonic scales are awesome:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;They&#39;re easy to hear.&lt;/li&gt; &lt;li&gt;They&#39;re easy to phrase.&lt;/li&gt; &lt;li&gt;They sit well over a range of chords.&lt;/li&gt; &lt;li&gt;They quickly sound musical, even before your theory knowledge is deep.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;On the guitar, the pentatonic scales work so well because they remove some of the strongest tension notes from the full scale. You can still create emotion and movement, but you&#39;re less likely to land on a note that feels harsh or unresolved by accident.&lt;/p&gt; &lt;p&gt;!!! note &#34;Why Pentatonics Feel So Friendly&#34; By removing some of the most tension-heavy notes from the full 7-note scale, pentatonics give you a leaner set of notes that is easier to phrase with confidence. That&#39;s why they&#39;re often the first scale family guitar players truly learn to hear.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/14/decoding-the-major-and-minor-pentatonic-scales/</link> <pubDate>Sun, 14 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/14/decoding-the-major-and-minor-pentatonic-scales/</guid> </item> <item> <title>Hay for the Heifers</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>39 North</category> <category>Americana</category> <category>Country</category> <category>Music</category> <category>Songwriting</category> <category>Songwriting</category> <description>&lt;p&gt;!!! note &#34;Reflection&#34;&lt;/p&gt; &lt;pre&gt;&lt;code&gt;Farm work looks noble from a distance, viewed through the softening lens of years gone by. But it was just sweat, salt, and t... &lt;/code&gt;&lt;/pre&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/11/hay-for-the-heifers/</link> <pubDate>Thu, 11 Jun 2026 00:00:01 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/11/hay-for-the-heifers/</guid> </item> <item> <title>Nginx: A Practical Deep Dive</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>DevOps</category> <category>Developer Workflow</category> <category>Infrastructure-as-Code</category> <category>Linux</category> <category>Load Balancing</category> <category>Nginx</category> <category>Reverse Proxy</category> <category>Security</category> <category>Technology</category> <category>Web Servers</category> <description>&lt;p&gt;Nginx ends up in front of a surprising amount of web traffic. You might not think much about it until you have to troubleshoot a redirect loop, a broken certificate renewal, or an application that only fails once it sits behind a proxy.&lt;/p&gt; &lt;p&gt;Static sites, application servers, APIs, internal tools, container platforms, and CDN origins often have Nginx somewhere out front. People keep using it because it&#39;s fast, it&#39;s predictable, and it makes you declare what the server should do.&lt;/p&gt; &lt;p&gt;This guide walks through the part that matters in practice: what Nginx is good at, how its config model works, how to install it, how to serve a site, how to terminate TLS, how to replace &lt;code&gt;.htaccess&lt;/code&gt; style behavior the Nginx way, and how to use it as a reverse proxy and a basic load balancer.&lt;/p&gt; &lt;p&gt;Nginx is a web server, reverse proxy, and load balancer. In a modern stack it usually does one or more of these jobs:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Serves static files directly.&lt;/li&gt; &lt;li&gt;Terminates HTTPS connections.&lt;/li&gt; &lt;li&gt;Redirects HTTP to HTTPS.&lt;/li&gt; &lt;li&gt;Proxies requests to application servers.&lt;/li&gt; &lt;li&gt;Balances traffic across multiple backend services.&lt;/li&gt; &lt;li&gt;Adds request and response headers.&lt;/li&gt; &lt;li&gt;Buffers slow clients away from backend applications.&lt;/li&gt; &lt;li&gt;Enforces simple access control rules.&lt;/li&gt; &lt;li&gt;Caches upstream responses when configured to do so.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;It&#39;s especially good at static assets, reverse proxying, and a lot of concurrent connections. It also works well as the boring edge layer in front of applications written in Node.js, Python, Go, Ruby, PHP, Java, or anything else that can listen on a port.&lt;/p&gt; &lt;p&gt;The simplest mental model:&lt;/p&gt; &lt;p&gt;&lt;code&gt;mermaid graph TD A[Client Browser] --&amp;gt;|HTTPS Request| B[Nginx] B --&amp;gt;|HTTP Request to Local App| C[Backend Application]&lt;/code&gt;&lt;/p&gt; &lt;p&gt;Nginx does not need to understand your application. It just needs to accept the request, apply the rules you gave it, and either serve the response or pass the request upstream.&lt;/p&gt; &lt;p&gt;Nginx became popular because it handles several common infrastructure problems without much drama:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;It handles many concurrent connections efficiently.&lt;/li&gt; &lt;li&gt;It serves static files quickly.&lt;/li&gt; &lt;li&gt;It&#39;s excellent as a reverse proxy.&lt;/li&gt; &lt;li&gt;It&#39;s good at shielding backend apps from awkward client behavior.&lt;/li&gt; &lt;li&gt;It centralizes TLS, redirects, headers, and access control.&lt;/li&gt; &lt;li&gt;It can load balance traffic without a separate appliance.&lt;/li&gt; &lt;li&gt;Its configuration is explicit and reviewable.&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Nginx expects configuration in known files, not hidden per-directory overrides inside the document root. That makes behavior easier to inspect, version, test, and deploy.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/11/nginx-a-practical-deep-dive/</link> <pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/11/nginx-a-practical-deep-dive/</guid> </item> <item> <title>VMware Workstation and Fusion 26H1 Release</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Desktop Hypervisor</category> <category>Developer Experience</category> <category>Technology</category> <category>VMware Fusion</category> <category>VMware Workstation</category> <description>&lt;p&gt;VMware Workstation Pro and Fusion Pro 26H1 shipped recently and was a fairly quiet release. &lt;/p&gt; &lt;p&gt;The biggest change in Workstation Pro 26H1 is the move to a ful...&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/07/vmware-workstation-and-fusion-26h1-release/</link> <pubDate>Sun, 07 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/07/vmware-workstation-and-fusion-26h1-release/</guid> </item> <item> <title>How I&#39;m Preparing for GH-600, GitHub&#39;s Agentic AI Developer Certification</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Artificial Intelligence</category> <category>Certifications</category> <category>Developer Experience</category> <category>GitHub</category> <category>GitHub Copilot</category> <category>Learning</category> <category>Technology</category> <description>&lt;p&gt;&lt;img alt=&#34;GitHub Certification&#34; src=&#34;../images/post-github-certifications-overview.png&#34;&gt;{ align=right width=175 }&lt;/p&gt; &lt;p&gt;When I published &lt;a href=&#34;2026-04-03-github-certifications.md&#34;&gt;Branching Out: GitHub Certification Path&lt;/a&gt;, GitHub had five certifications. That list is already out of date, and so is my own exam roadmap.&lt;/p&gt; &lt;p&gt;GitHub has now added a sixth exam: &lt;strong&gt;GH-600, GitHub Certified: Agentic AI Developer (beta)&lt;/strong&gt;. As of June 6, 2026, this one is still in beta, and it fills a different role than the existing Copilot certification. The Copilot exam is about using GitHub&#39;s AI tooling well. GH-600 is about building, operating, constraining, and evaluating agents inside real software delivery workflows.&lt;/p&gt; &lt;p&gt;I&#39;m treating this post as my preparation plan for GH-600. These are the official materials, docs, and hands-on exercises I&#39;m using to get ready for it.&lt;/p&gt; &lt;p&gt;GitHub is treating agentic AI as an engineering discipline: tool access, MCP configuration, execution boundaries, memory, observability, evaluation, and guardrails. That&#39;s the right frame for the technology, and it&#39;s the reason this exam is worth taking seriously.&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/06/how-im-preparing-for-gh-600-githubs-agentic-ai-developer-certification/</link> <pubDate>Sat, 06 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/06/how-im-preparing-for-gh-600-githubs-agentic-ai-developer-certification/</guid> </item> <item> <title>Versioning Documentation with ProperDocs and mike</title> <author>ryan@tenthirtyam.org (Ryan Johnson)</author> <category>Developer Workflow</category> <category>Documentation</category> <category>MkDocs</category> <category>Open Source</category> <category>ProperDocs</category> <category>Technology</category> <description>&lt;p&gt;If you&#39;re using ProperDocs, versioned publishing should be straightforward. Build the docs for a release, publish them under a stable version label, and leave older versions alone. Until &lt;code&gt;mike&lt;/code&gt; v2.2.0, that simple workflow still carried a nagging question: did the rest of the tooling really understand ProperDocs, or was it still assuming MkDocs under the hood?&lt;/p&gt; &lt;p&gt;&lt;a href=&#34;https://github.com/jimporter/mike&#34;&gt;&lt;code&gt;mike&lt;/code&gt;&lt;/a&gt; publishes each supported release as its own directory tree on a deployment branch, usually &lt;code&gt;gh-pages&lt;/code&gt;. Old versions stay put even when today&#39;s main branch moves on. In the &lt;a href=&#34;https://github.com/jimporter/mike/releases/tag/v2.2.0&#34;&gt;mike v2.2.0 release&lt;/a&gt;, that process got simpler for ProperDocs users: when the &lt;code&gt;properdocs&lt;/code&gt; package is installed, &lt;code&gt;mike&lt;/code&gt; runs &lt;code&gt;properdocs&lt;/code&gt; instead of &lt;code&gt;mkdocs&lt;/code&gt;. No separate workflow branch. No wrapper script. No extra switch to remember.&lt;/p&gt; &lt;p&gt;The release notes include:&lt;/p&gt; &lt;blockquote&gt; &lt;p&gt;Add support for ProperDocs.&lt;/p&gt; &lt;/blockquote&gt; &lt;p&gt;In practice, that means &lt;code&gt;mike&lt;/code&gt; now checks for the &lt;code&gt;properdocs&lt;/code&gt; package first. When it&#39;s present, &lt;code&gt;mike&lt;/code&gt; uses the &lt;code&gt;properdocs&lt;/code&gt; command and includes &lt;code&gt;properdocs.yml&lt;/code&gt; and &lt;code&gt;properdocs.yaml&lt;/code&gt; in its default configuration file search order.&lt;/p&gt; &lt;p&gt;That is exactly the kind of compatibility work you want in a documentation pipeline. Install the generator you actually use, install &lt;code&gt;mike&lt;/code&gt;, and let tool detection do the boring part correctly.&lt;/p&gt; &lt;p&gt;ProperDocs exists because some teams need the MkDocs 1.x operating model to keep working. They have plugins, theme overrides, snippets, macros, and workflow assumptions built around that ecosystem. Versioned publishing shouldn&#39;t force those teams into a second set of build logic.&lt;/p&gt; &lt;p&gt;Before this change, the friction wasn&#39;t that versioned docs were impossible. The friction was that ProperDocs users had to think too much about whether the surrounding tooling still assumed MkDocs. That extra uncertainty is how CI jobs grow unnecessary conditionals and side paths.&lt;/p&gt; &lt;p&gt;With &lt;code&gt;mike&lt;/code&gt; v2.2.0, the command flow is really simple:&lt;/p&gt; &lt;p&gt;&lt;code&gt;bash python -m pip install &#34;properdocs&#34; &#34;mike&amp;gt;=2.2.0&#34; mike deploy 1.0 latest --push&lt;/code&gt;&lt;/p&gt;</description> <link>https://tenthirtyam.org/dispatches/2026/06/05/versioning-documentation-with-properdocs-and-mike/</link> <pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate> <source url="https://tenthirtyam.org/rss.xml">Hypertext Dispatches</source><guid isPermaLink="true">https://tenthirtyam.org/dispatches/2026/06/05/versioning-documentation-with-properdocs-and-mike/</guid> </item> </channel> </rss>