<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>bradleyboy.com</title>
  <subtitle>The online home of Brad Daily.</subtitle>
  <link href="https://www.bradleyboy.com/feed.xml" rel="self"/>
  <link href="https://www.bradleyboy.com/"/>
  <updated>2026-04-09T00:00:00Z</updated>
  <id>https://www.bradleyboy.com/</id>
  <author>
    <name>Brad Daily</name>
  </author>
  <entry>
    <title>Reviving Koken</title>
    <link href="https://www.bradleyboy.com/writings/reviving-koken/"/>
    <updated>2026-04-09T00:00:00Z</updated>
    <id>https://www.bradleyboy.com/writings/reviving-koken/</id>
    <content type="html">&lt;p&gt;In another tech-life, I helped run a small software shop with designer/developer Todd Dominey. Out of that shop came a few products. First was &lt;a href=&quot;http://slideshowpro.com/&quot;&gt;SlideShowPro&lt;/a&gt;, a Flash-based slideshow system with an accompanying CMS (SlideShowPro Director). SlideShowPro was a commercial hit and used all over the web at the time. But it was tied to Flash, and the surge of mobile browsers with their lack of Flash support induced a slow death starting with the initial release of the iPad in 2010 &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fn1&quot; id=&quot;fnref1&quot;&gt;[1]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;On the heels of SlideShowPro, developer Lauren Smith joined us and we created &lt;a href=&quot;https://koken.me/&quot;&gt;Koken&lt;/a&gt;, a self-hosted, website publishing system for photographers. While Koken never reached the same commercial success as SlideShowPro, it is still the project in my career I am most proud of. That pride is rooted in all we had to invent along the way: a custom templating language, our own SPA framework, over-the-wire updates, a &lt;a href=&quot;https://web.archive.org/web/20201112021654/http://blog.koken.me/essays/2014/02/koken-store-sneak-preview/&quot;&gt;store&lt;/a&gt; for themes and plugins, to name a few. And it was all housed in a UI that was as intentional as it was beautiful.&lt;/p&gt;
&lt;p&gt;Sadly, we ran out of gas (both emotionally and financially) and sold Koken to another company in 2015. That company tried to push forward for a few years, but eventually disappeared, and Todd and I started hearing from users a few years later that their installs of Koken were breaking down. We tried to work out an arrangement with the new owner to take over and prop it back up, but lost contact again. Koken&#39;s stability continued to decay and it gently eased over the internet horizon as the years passed.&lt;/p&gt;
&lt;p&gt;The thought of trying to revive Koken was always daunting to me, who knows how long it would take to fix the years of neglect. But recently, with the emergence of AI tooling, my curiosity got the best of me.&lt;/p&gt;
&lt;p&gt;Could I use something like Claude Code to reanimate Koken&#39;s codebase, without burning weeks of time I did not have?&lt;/p&gt;
&lt;p&gt;And if it could do this now, what would Koken&#39;s story have been if we&#39;d had these tools then? Would the leverage have bought us the time we ran out of?&lt;/p&gt;
&lt;h2&gt;Catching up with an old friend&lt;/h2&gt;
&lt;p&gt;I once had an encyclopedic knowledge of Koken&#39;s codebase, but the passage of time and three jobs in large codebases since had erased all of that, so I started by cloning the repo and asking simple questions about its timeline and stack.&lt;/p&gt;
&lt;p&gt;Koken has a dense history for such a small team: 18,145 total commits across ~7 years dating back to the initial commit on Dec 29th, 2010:&lt;/p&gt;
&lt;pre class=&quot;language-txt&quot;&gt;&lt;code class=&quot;language-txt&quot;&gt;Author: bdaily
Date:   Wed Dec 29 19:58:25 2010 +0000

D2 becomes director-dev

git-svn-id: [removed for brevity]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Koken&#39;s life began as &amp;quot;Director 2&amp;quot; — a would-be new major release of SlideShowPro Director — but we eventually pivoted to a new brand for a variety of reasons.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;git-svn-id&lt;/code&gt; metadata caught my eye, reminding me that for years we used &lt;a href=&quot;https://en.wikipedia.org/wiki/Apache_Subversion&quot;&gt;SVN (Subversion)&lt;/a&gt;, a version control system that predated Git. At some point in Koken&#39;s development we moved to Git and GitHub, along with the rest of the industry &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fn2&quot; id=&quot;fnref2&quot;&gt;[2]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Here&#39;s what the commit activity looked like over the years, easy to spot our collective burnout:&lt;/p&gt;
&lt;div style=&quot;background: #1a2e1a; border: 1px solid #2a4a2a; border-radius: 6px; padding: 1rem 1.25rem 1rem; margin: 1.5rem 0; max-width: 42rem;&quot;&gt;
&lt;div style=&quot;font-size: 0.8rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; color: #d5ddd5; margin-bottom: 0.75rem;&quot;&gt;Commits to Koken (2010-2017)&lt;/div&gt;
&lt;svg viewBox=&quot;0 0 672 275&quot; xmlns=&quot;http://www.w3.org/2000/svg&quot; role=&quot;img&quot; aria-label=&quot;Bar chart showing Koken commit activity from 2010 to 2017, peaking at 5,118 commits in 2013&quot; style=&quot;width: 100%; display: block;&quot;&gt;
  &lt;style&gt;
    .chart-bar { fill: #85e89d; }
    .chart-bar:hover { fill: #b5f5b5; }
    .chart-count { fill: #d5ddd5; font-family: &quot;SFMono-Regular&quot;, Consolas, monospace; font-size: 13px; text-anchor: middle; font-weight: 500; }
    .chart-axis { stroke: #5a8a5a; stroke-width: 1; }
    .chart-year { fill: #c5ddc5; font-family: &quot;SFMono-Regular&quot;, Consolas, monospace; font-size: 13px; text-anchor: middle; }
    .chart-grid { stroke: #5a8a5a; stroke-width: 0.5; stroke-dasharray: 3,4; }
    .chart-grid-label { fill: #6e9a6e; font-family: &quot;SFMono-Regular&quot;, Consolas, monospace; font-size: 11px; }
  &lt;/style&gt;
  &lt;!-- Grid lines with left-aligned labels (x=0, matching title alignment) --&gt;
  &lt;!-- Chart area: y=30..240, 210px height, max value 5000 (round scale) --&gt;
  &lt;!-- 0=y240, 1000=y198, 2000=y156, 3000=y114, 4000=y72, 5000=y30 --&gt;
  &lt;text class=&quot;chart-grid-label&quot; x=&quot;0&quot; y=&quot;202&quot;&gt;1k&lt;/text&gt;
  &lt;line class=&quot;chart-grid&quot; x1=&quot;28&quot; y1=&quot;198&quot; x2=&quot;672&quot; y2=&quot;198&quot;&gt;&lt;/line&gt;
  &lt;text class=&quot;chart-grid-label&quot; x=&quot;0&quot; y=&quot;160&quot;&gt;2k&lt;/text&gt;
  &lt;line class=&quot;chart-grid&quot; x1=&quot;28&quot; y1=&quot;156&quot; x2=&quot;672&quot; y2=&quot;156&quot;&gt;&lt;/line&gt;
  &lt;text class=&quot;chart-grid-label&quot; x=&quot;0&quot; y=&quot;118&quot;&gt;3k&lt;/text&gt;
  &lt;line class=&quot;chart-grid&quot; x1=&quot;28&quot; y1=&quot;114&quot; x2=&quot;672&quot; y2=&quot;114&quot;&gt;&lt;/line&gt;
  &lt;text class=&quot;chart-grid-label&quot; x=&quot;0&quot; y=&quot;76&quot;&gt;4k&lt;/text&gt;
  &lt;line class=&quot;chart-grid&quot; x1=&quot;28&quot; y1=&quot;72&quot; x2=&quot;672&quot; y2=&quot;72&quot;&gt;&lt;/line&gt;
  &lt;text class=&quot;chart-grid-label&quot; x=&quot;0&quot; y=&quot;34&quot;&gt;5k&lt;/text&gt;
  &lt;line class=&quot;chart-grid&quot; x1=&quot;28&quot; y1=&quot;30&quot; x2=&quot;672&quot; y2=&quot;30&quot;&gt;&lt;/line&gt;
  &lt;!-- Bars: scale 0..5000 over 210px. barWidth=66, gap=16, start x=30 --&gt;
  &lt;!-- 2010: 2 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;30&quot; y=&quot;239&quot; width=&quot;66&quot; height=&quot;1&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;63&quot; y=&quot;232&quot;&gt;2&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;63&quot; y=&quot;265&quot;&gt;2010&lt;/text&gt;
  &lt;!-- 2011: 2438, h=102 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;112&quot; y=&quot;138&quot; width=&quot;66&quot; height=&quot;102&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;145&quot; y=&quot;131&quot;&gt;2,438&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;145&quot; y=&quot;265&quot;&gt;2011&lt;/text&gt;
  &lt;!-- 2012: 3981, h=167 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;194&quot; y=&quot;73&quot; width=&quot;66&quot; height=&quot;167&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;227&quot; y=&quot;66&quot;&gt;3,981&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;227&quot; y=&quot;265&quot;&gt;2012&lt;/text&gt;
  &lt;!-- 2013: 5118, h=215 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;276&quot; y=&quot;25&quot; width=&quot;66&quot; height=&quot;215&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;309&quot; y=&quot;18&quot;&gt;5,118&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;309&quot; y=&quot;265&quot;&gt;2013&lt;/text&gt;
  &lt;!-- 2014: 3277, h=138 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;358&quot; y=&quot;102&quot; width=&quot;66&quot; height=&quot;138&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;391&quot; y=&quot;95&quot;&gt;3,277&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;391&quot; y=&quot;265&quot;&gt;2014&lt;/text&gt;
  &lt;!-- 2015: 484, h=20 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;440&quot; y=&quot;220&quot; width=&quot;66&quot; height=&quot;20&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;473&quot; y=&quot;213&quot;&gt;484&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;473&quot; y=&quot;265&quot;&gt;2015&lt;/text&gt;
  &lt;!-- 2016: 396, h=17 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;522&quot; y=&quot;223&quot; width=&quot;66&quot; height=&quot;17&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;555&quot; y=&quot;216&quot;&gt;396&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;555&quot; y=&quot;265&quot;&gt;2016&lt;/text&gt;
  &lt;!-- 2017: 113, h=5 --&gt;
  &lt;rect class=&quot;chart-bar&quot; x=&quot;604&quot; y=&quot;235&quot; width=&quot;66&quot; height=&quot;5&quot; rx=&quot;3&quot;&gt;&lt;/rect&gt;
  &lt;text class=&quot;chart-count&quot; x=&quot;637&quot; y=&quot;228&quot;&gt;113&lt;/text&gt;
  &lt;text class=&quot;chart-year&quot; x=&quot;637&quot; y=&quot;265&quot;&gt;2017&lt;/text&gt;
&lt;/svg&gt;
&lt;/div&gt;
&lt;p&gt;Our release process used git tags, which also allowed me to visualize the release timeline. The first alpha release of Koken was cut in July of 2012. Koken&#39;s last tag (&lt;code&gt;0.22.24&lt;/code&gt;) was released in August of 2017, never reaching 1.0.&lt;/p&gt;
&lt;p&gt;Koken&#39;s tech stack is a time capsule of that period. Notably, Koken was self-hosted, and built to work on any run-of-the-mill shared PHP host, of which there were many at the time &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fn3&quot; id=&quot;fnref3&quot;&gt;[3]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP with &lt;a href=&quot;https://www.codeigniter.com/&quot;&gt;CodeIgniter&lt;/a&gt; as the framework&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;A custom SPA JavaScript framework for the admin, using Knockout.js for reactivity.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gulpjs.com/&quot;&gt;Gulp&lt;/a&gt; was used as the build system&lt;/li&gt;
&lt;li&gt;Roughly 250K lines of code, when excluding vendored dependencies like CodeIgniter and Knockout.js&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;So how does this thing work again?&lt;/h2&gt;
&lt;p&gt;The deep dive on the codebase jogged my memory at a high level, but I still couldn&#39;t remember how to even run Koken locally. So, I prompted Claude, simply:&lt;/p&gt;
&lt;blockquote&gt;
&lt;header&gt;Me&lt;/header&gt;
i haven&#39;t run this in a long time, devise a plan to run this locally          
&lt;/blockquote&gt;
&lt;p&gt;I did not have high hopes for this. But Claude delivered a plan that seemed promising, and addressed the main concerns (PHP/MySQL compatibility issues):&lt;/p&gt;
&lt;blockquote&gt;
&lt;header&gt;Claude&lt;/header&gt;
The plan is to use Docker Compose with PHP 7.4 + Apache and MySQL 5.7 — the
safest way to run this 2011-2017 era codebase without fighting PHP
compatibility issues. I&#39;ll create a Dockerfile, docker-compose.yml, ensure
storage permissions, and get the Koken installer accessible at
localhost:8080/admin/.
&lt;/blockquote&gt;
&lt;p&gt;It made no mention of a build step for the JavaScript, which seemed wrong. Turns out, my memory faltered here — in development, we had a PHP shim that was responsible for concatenating JS and CSS. 2011 was a simpler time!&lt;/p&gt;
&lt;h2&gt;What&#39;s the worst that could happen?&lt;/h2&gt;
&lt;p&gt;So, with tokens from my subscription burning a hole in my pocket, I told Claude to go for it. I had &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt; on — a Claude option that doesn&#39;t ask for your approval at each step — so it churned for a bit while I got on with my Saturday. I checked back in after 15 minutes or so and was surprised to see it had confidently arrived at a half-working installation (according to Claude, just the administration panel was functional, the site that Koken published from your data was not). It hit a few Docker bumps along the way, but self-corrected immediately each time. And it &lt;em&gt;did&lt;/em&gt; work. I could see the admin login screen in my browser, but couldn&#39;t login.&lt;/p&gt;
&lt;p&gt;Claude was prompting me to &amp;quot;run the installer&amp;quot;, but I knew we had a different way of installing in development. I nudged Claude in that direction, and it found a &lt;code&gt;gulp reset&lt;/code&gt; task we used in the now defunct Vagrant workflow, then ported the whole thing to a Docker-compatible script in one pass.&lt;/p&gt;
&lt;h2&gt;The slog&lt;/h2&gt;
&lt;p&gt;With the reset done and the database alive, the real fun started: PHP compatibility issues. Koken&#39;s codebase was written for PHP 5.3, a now unsupported, insecure PHP version. Claude began iterating through all of the necessary fixes to get things working on 7.4. Honestly, just watching this fly by in Claude&#39;s output, I thought we were headed for failure, and this is where I probably would have quit had I tried this unassisted. From the outside, it looked like the worst game of whack-a-mole ever. But Claude plowed through with a meticulous debug loop, addressing each compatibility issue until things just...worked.&lt;/p&gt;
&lt;p&gt;I opened the login page and used the credentials Claude gave me. And there it was, the interface I remembered. Just one problem: none of the images showed up in the interface. An important feature for a photography application!&lt;/p&gt;
&lt;h2&gt;The loopback&lt;/h2&gt;
&lt;p&gt;I fed one of the breaking image URLs to Claude to investigate. Two important things about Koken&#39;s architecture to know at this point. First, we never rendered the original image, as photographers usually uploaded high quality images and Koken resized and cached them just-in-time to render at the right size and retina resolution. Second, I was obsessed with API-first design at the time. In practice, there was no direct access to the database outside of Koken&#39;s API endpoints. Even something like the image rendering path would hit the API internally for the necessary information, then render out and cache the image.&lt;/p&gt;
&lt;p&gt;This architecture worked well from a &amp;quot;single source of truth&amp;quot; perspective, but we constantly ran into issues due to &amp;quot;loopback&amp;quot; connections. A loopback connection is when a server makes an HTTP call that resolves to itself over &lt;code&gt;localhost&lt;/code&gt; or &lt;code&gt;127.0.0.1&lt;/code&gt;. And it turns out, this was what was breaking down when trying to render images in the revival stack.&lt;/p&gt;
&lt;p&gt;The issue was due to Docker&#39;s networking abstraction, and instead of hacking around it Claude went a level deeper and found a built-in mechanism in Koken&#39;s configuration that fixed loopback issues like this, a setting named &lt;code&gt;LOOPBACK_HOST_HEADER&lt;/code&gt;. This option forced the internal HTTP calls to use the server&#39;s address (IP) and explicit port. Setting &lt;code&gt;LOOPBACK_HOST_HEADER&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; appeared to fix the issue. One image loaded, but the others still failed. I pushed Claude to continue investigating.&lt;/p&gt;
&lt;p&gt;What it found was actually a gap in &lt;code&gt;LOOPBACK_HOST_HEADER&lt;/code&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;header&gt;Claude&lt;/header&gt;
The LOOPBACK_HOST_HEADER flag was designed for cases where SERVER_ADDR is different from HTTP_HOST (like a proxy), but it still trusts SERVER_PORT. In Docker, SERVER_PORT is wrong. I can either fix this in Koken API or make it configurable. Let me make LOOPBACK_HOST_HEADER accept a string value (the host:port to use) instead of just true.
&lt;/blockquote&gt;
&lt;p&gt;This is a reasonable fix, and probably something we should have done way back when. With the fix in place, all the images loaded. I was transported back to 2011.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bradleyboy.com/images/koken-library.png&quot; alt=&quot;Koken&#39;s library interface showing the user&#39;s albums and images&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;It&#39;s alive&lt;/h2&gt;
&lt;p&gt;After looking through the admin panel, I was excited to see the published site. Earlier, Claude had flagged that this part as broken. It turned out to be a similar loopback issue — our previous fixes also applied here. I opened the published site and the default theme loaded just as it was designed over a decade ago. The name of the site caught my eye.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sebastian Pinehurst&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This was the fake photographer persona that we published the development version of Koken under, and I immediately fired off an email to Todd. Subject line:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sebastian Pinehurst lives&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I continued tinkering a bit, and along the way had Claude write notes in an &lt;code&gt;archaeology&lt;/code&gt; directory on all our little discoveries. I even had it try its hand at developing a new theme, which it was able to do without much trouble &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fn4&quot; id=&quot;fnref4&quot;&gt;[4]&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;I spent what felt like another hour clicking around and rediscovering Koken. Nostalgia came in waves. I was amazed at how well the UI held up, and at all the little details I had forgotten.&lt;/p&gt;
&lt;h2&gt;Postlude&lt;/h2&gt;
&lt;p&gt;All of this — from the start of the repo exploration, until I fired off that email to Todd — happened within the span of about 1 hour &lt;sup class=&quot;footnote-ref&quot;&gt;&lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fn5&quot; id=&quot;fnref5&quot;&gt;[5]&lt;/a&gt;&lt;/sup&gt;. Claude had picked Koken off the floor, barely alive, and breathed new life into it. It was nostalgic, but it also felt empty in a way I didn&#39;t expect.&lt;/p&gt;
&lt;p&gt;Building something like this is &lt;em&gt;hard work&lt;/em&gt;, and we often obsessed over small details to get them just right, or spent days debugging a thorny issue. The valleys in this work can be dark, frustrating, hopeless. But that is also the hook: when you land just the right detail, find the needle-in-the-haystack cause of a bug, the rush is irreplaceable.&lt;/p&gt;
&lt;p&gt;Yes, Claude had done what seemed like a miracle. But it did so mostly alone — I was there, but how necessary was I? The original team was scattered to the wind and unable to share in the accomplishment.&lt;/p&gt;
&lt;p&gt;Grinding through those fixes over weeks with Todd and Lauren would have been slower, uglier, more ours. The burnout that killed Koken and the pride I still carry come from the same place: years of invention, obsession over detail, and a shared stubbornness about when good enough was good enough. Claude revived the product itself, but did so with no need for the &lt;em&gt;experience&lt;/em&gt; of building it. Time will tell whether that experience matters in this new age.&lt;/p&gt;
&lt;p&gt;Long live Sebastian Pinehurst.&lt;/p&gt;
&lt;hr class=&quot;footnotes-sep&quot; /&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn1&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Although we did stem the tide a bit with the introduction of &lt;a href=&quot;https://web.archive.org/web/20141202182620/http://slideshowpro.net/news/archive/2010/07/announcing-slideshowpro-mobile.php/&quot;&gt;SlideShowPro Mobile&lt;/a&gt;, but that&#39;s a story for another time. &lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fnref1&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn2&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;For some reason, I always liked how SVN&#39;s main branch was called &amp;quot;trunk&amp;quot;. &lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fnref2&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn3&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;I could devote a separate post for all the wacky things I found these shared hosts doing over the years. &lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fnref3&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn4&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Other than the usual vanilla AI design aesthetic. &lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fnref4&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;fn5&quot; class=&quot;footnote-item&quot;&gt;&lt;p&gt;Token cost was ~100K, less than $5. &lt;a href=&quot;https://www.bradleyboy.com/writings/reviving-koken/#fnref5&quot; class=&quot;footnote-backref&quot;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;
</content>
  </entry>
</feed>
