<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>David Duncan's Personal Blog - Technology</title><link href="https://davidduncan.org/" rel="alternate"/><link href="https://davidduncan.org/feeds/technology.atom.xml" rel="self"/><id>https://davidduncan.org/</id><updated>2026-05-30T09:30:00-05:00</updated><entry><title>A Molokai Palette for the Gum Pelican Theme</title><link href="https://davidduncan.org/molokai-palette-for-gum.html" rel="alternate"/><published>2026-05-30T09:30:00-05:00</published><updated>2026-05-30T09:30:00-05:00</updated><author><name>David Duncan</name></author><id>tag:davidduncan.org,2026-05-30:/molokai-palette-for-gum.html</id><summary type="html">&lt;p&gt;I switched this blog from Pelican&amp;#8217;s default theme to gum, fixed an upstream column-grid bug that had been hiding the sidebar, regenerated the code highlighting with monokai, and layered a full Molokai palette over the top — without forking the theme. Here&amp;#8217;s the recipe, plus a drop-in &lt;span class="caps"&gt;CSS&lt;/span&gt; file for anyone else running&amp;nbsp;gum.&lt;/p&gt;</summary><content type="html">&lt;p&gt;This blog has been running on Pelican&amp;#8217;s&amp;nbsp;default &lt;code&gt;notmyidea&lt;/code&gt; theme for a long time. It works, but the look is dated and there was no way to take real control of layout or navigation without forking the theme. I wanted three things: a real templated theme (so I can change structure later), a layout that actually surfaces a sidebar, and a color scheme I&amp;#8217;d enjoy looking at. Molokai has been my editor palette for years, so that was the&amp;nbsp;destination.&lt;/p&gt;
&lt;p&gt;The result is what you&amp;#8217;re looking at now: the &lt;a href="https://github.com/getpelican/pelican-themes/tree/master/gum"&gt;gum theme&lt;/a&gt;&amp;nbsp;from &lt;code&gt;getpelican/pelican-themes&lt;/code&gt;, with two small upstream fixes and a Molokai overlay applied as&amp;nbsp;a &lt;code&gt;CUSTOM_CSS_FILES&lt;/code&gt; layer. No theme fork&amp;nbsp;required.&lt;/p&gt;
&lt;h2&gt;Why&amp;nbsp;gum&lt;/h2&gt;
&lt;p&gt;Gum is one of the older community themes&amp;nbsp;in &lt;code&gt;getpelican/pelican-themes&lt;/code&gt;. It uses the (now-archived) Gumby Framework for its 12-column grid, and it ships with jQuery 1.9.1 + Modernizr 2.6.2, so it is showing its age. What it has going for it is honest structure:&amp;nbsp;a &lt;code&gt;base.html&lt;/code&gt;, real Jinja2 templates for index, article, page, archives, tags, categories, and a sidebar — all in plain &lt;span class="caps"&gt;HTML&lt;/span&gt; you can read in an afternoon. That makes it a good starting point for someone who plans to edit the templates themselves rather than treat the theme as a closed&amp;nbsp;box.&lt;/p&gt;
&lt;h2&gt;The sidebar wasn&amp;#8217;t&amp;nbsp;showing&lt;/h2&gt;
&lt;p&gt;The first thing I noticed after switching was that gum&amp;#8217;s sidebar didn&amp;#8217;t render beside the content. It rendered, just not where you&amp;#8217;d expect. The cause turned out to be a simple math mistake in the upstream&amp;nbsp;templates:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cm"&gt;&amp;lt;!-- theme-gum/templates/index.html --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;row&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;eleven columns&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;      &lt;span class="cm"&gt;&amp;lt;!-- 11 --&amp;gt;&lt;/span&gt;
        ... article list ...
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    {% include &amp;#39;sidebar.html&amp;#39; %}      &lt;span class="cm"&gt;&amp;lt;!-- includes a &amp;quot;three columns&amp;quot; div --&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The sidebar is&amp;nbsp;a &lt;code&gt;three columns&lt;/code&gt; div. 11 + 3 = 14, which overflows Gumby&amp;#8217;s 12-column grid, so the sidebar wraps below the content instead of sitting next to it. The fix is to make the content&amp;nbsp;area &lt;code&gt;nine columns&lt;/code&gt; so 9 + 3 = 12 fits cleanly. The same fix applies&amp;nbsp;to &lt;code&gt;article.html&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After that the sidebar shows up exactly where it was always meant to — categories, social links, the&amp;nbsp;lot.&lt;/p&gt;
&lt;h2&gt;Code highlighting:&amp;nbsp;regenerate &lt;code&gt;pygment.css&lt;/code&gt; with &lt;code&gt;.highlight&lt;/code&gt; scoping&lt;/h2&gt;
&lt;p&gt;Pelican&amp;#8217;s markdown extension wraps code blocks in&amp;nbsp;a &lt;code&gt;.highlight&lt;/code&gt; div. Gum&amp;#8217;s&amp;nbsp;bundled &lt;code&gt;pygment.css&lt;/code&gt; uses no parent class prefix, which means its rules apply to&amp;nbsp;any &lt;code&gt;.c&lt;/code&gt;, &lt;code&gt;.k&lt;/code&gt;, &lt;code&gt;.s&lt;/code&gt; token on the page — not just inside code blocks. That&amp;#8217;s the kind of scoping bug that explodes in subtle ways once you write inline markdown that happens to contain those class&amp;nbsp;names.&lt;/p&gt;
&lt;p&gt;The fix is one shell command. Pygments ships with a&amp;nbsp;built-in &lt;code&gt;monokai&lt;/code&gt; style — the canonical syntax-highlighting form of&amp;nbsp;Molokai:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;pygmentize&lt;span class="w"&gt; &lt;/span&gt;-S&lt;span class="w"&gt; &lt;/span&gt;monokai&lt;span class="w"&gt; &lt;/span&gt;-f&lt;span class="w"&gt; &lt;/span&gt;html&lt;span class="w"&gt; &lt;/span&gt;-a&lt;span class="w"&gt; &lt;/span&gt;.highlight&lt;span class="w"&gt; &lt;/span&gt;&amp;gt;&lt;span class="w"&gt; &lt;/span&gt;theme-gum/static/pygment.css
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;-a .highlight&lt;/code&gt; flag prefixes every rule&amp;nbsp;with &lt;code&gt;.highlight&lt;/code&gt;, so the colors only apply inside actual code blocks. Drop-in&amp;nbsp;replacement.&lt;/p&gt;
&lt;h2&gt;The site palette: a CUSTOM_CSS_FILES&amp;nbsp;overlay&lt;/h2&gt;
&lt;p&gt;For the rest of the site I didn&amp;#8217;t want to edit&amp;nbsp;gum&amp;#8217;s &lt;code&gt;style.css&lt;/code&gt; or &lt;code&gt;gumby.css&lt;/code&gt; directly. Editing the theme&amp;#8217;s own &lt;span class="caps"&gt;CSS&lt;/span&gt; means every future change is a merge conflict with upstream, and it muddies what&amp;#8217;s structural vs. what&amp;#8217;s cosmetic. Gum exposes a much cleaner hook:&amp;nbsp;the &lt;code&gt;CUSTOM_CSS_FILES&lt;/code&gt; setting. Any path listed there is loaded &lt;em&gt;after&lt;/em&gt; the theme&amp;#8217;s own &lt;span class="caps"&gt;CSS&lt;/span&gt;, so the last definition&amp;nbsp;wins.&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;strategy:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Keep &lt;code&gt;gumby.css&lt;/code&gt;, &lt;code&gt;style.css&lt;/code&gt;,&amp;nbsp;and &lt;code&gt;pygment.css&lt;/code&gt; exactly as gum ships them (modulo&amp;nbsp;the &lt;code&gt;.highlight&lt;/code&gt; regeneration&amp;nbsp;above).&lt;/li&gt;
&lt;li&gt;Drop one new file&amp;nbsp;— &lt;code&gt;molokai.css&lt;/code&gt; —&amp;nbsp;into &lt;code&gt;theme-gum/static/&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tell &lt;code&gt;pelicanconf.py&lt;/code&gt; to load it&amp;nbsp;via &lt;code&gt;CUSTOM_CSS_FILES&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;# pelicanconf.py&lt;/span&gt;
&lt;span class="n"&gt;THEME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;theme-gum&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;PLUGIN_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;plugins&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;CUSTOM_CSS_FILES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;theme/molokai.css&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The file lives&amp;nbsp;at &lt;code&gt;theme-gum/static/molokai.css&lt;/code&gt;, which Pelican copies&amp;nbsp;to &lt;code&gt;output/theme/molokai.css&lt;/code&gt; — hence the relative&amp;nbsp;path &lt;code&gt;theme/molokai.css&lt;/code&gt; in the&amp;nbsp;setting.&lt;/p&gt;
&lt;h2&gt;The overlay&amp;nbsp;itself&lt;/h2&gt;
&lt;p&gt;The full Molokai palette goes in as &lt;span class="caps"&gt;CSS&lt;/span&gt; custom properties, then a small set of selectors maps them to gum&amp;#8217;s actual&amp;nbsp;structure:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;root&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="mh"&gt;#272822&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-soft&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="mh"&gt;#3e3d32&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-deep&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="mh"&gt;#1b1d1e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-fg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="mh"&gt;#f8f8f2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;   &lt;/span&gt;&lt;span class="mh"&gt;#75715e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="mh"&gt;#f92672&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-orange&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mh"&gt;#fd971f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-yellow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mh"&gt;#e6db74&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-green&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="mh"&gt;#a6e22e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-cyan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="mh"&gt;#66d9ef&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="nv"&gt;--molokai-purple&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="mh"&gt;#ae81ff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;body&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-fg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;banner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt;            &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-cyan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;banner&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-orange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;font-weight&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;normal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-deep&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt;     &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-fg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;hover&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;navigation&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;active&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-green&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt;                       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-cyan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;hover&lt;/span&gt;&lt;span class="w"&gt;                 &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-green&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;entry-title&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;entry-title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-cyan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;entry-title&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;hover&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-green&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;three&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;columns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;h4&lt;/span&gt;&lt;span class="w"&gt;       &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-red&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;three&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;columns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;a&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-cyan&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;btn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;primary&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-cyan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;btn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nd"&gt;hover&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-green&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;tag-row&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;label&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;label&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;danger&lt;/span&gt;&lt;span class="w"&gt;           &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-orange&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;code&lt;/span&gt;&lt;span class="w"&gt;                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-soft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-orange&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;highlight&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-deep&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;solid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-soft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;blockquote&lt;/span&gt;&lt;span class="w"&gt;              &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;border-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="kt"&gt;px&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;solid&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-purple&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-soft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;table&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;th&lt;/span&gt;&lt;span class="w"&gt;                &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-soft&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-yellow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nd"&gt;selection&lt;/span&gt;&lt;span class="w"&gt;             &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-yellow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nt"&gt;footer&lt;/span&gt;&lt;span class="p"&gt;#&lt;/span&gt;&lt;span class="nn"&gt;credits&lt;/span&gt;&lt;span class="w"&gt;          &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-bg-deep&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="w"&gt;                          &lt;/span&gt;&lt;span class="k"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;--molokai-comment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;A handful&amp;nbsp;of &lt;code&gt;!important&lt;/code&gt; flags survive in there because&amp;nbsp;gum&amp;#8217;s &lt;code&gt;gumby.css&lt;/code&gt; sets a few colors at high specificity&amp;nbsp;on &lt;code&gt;.btn&lt;/code&gt; variants and label classes. Those are the friction points; everything else flows from the palette&amp;nbsp;variables.&lt;/p&gt;
&lt;h2&gt;What it&amp;nbsp;costs&lt;/h2&gt;
&lt;p&gt;I want to be honest about the tradeoffs. Gum is old enough that it carries some weight you&amp;#8217;d think twice about on a green-field&amp;nbsp;theme:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;jQuery 1.9.1 (2013)&lt;/strong&gt; and &lt;strong&gt;Modernizr 2.6.2 (2013)&lt;/strong&gt; are loaded on every page. The site doesn&amp;#8217;t actually need&amp;nbsp;them.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gumby Framework&lt;/strong&gt; is archived. The 12-column grid still works; I just can&amp;#8217;t lean on the upstream for&amp;nbsp;fixes.&lt;/li&gt;
&lt;li&gt;The bundled icon font (Entypo) is mostly&amp;nbsp;unused.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a personal blog with six articles, none of that matters yet. If I later want a leaner &lt;span class="caps"&gt;JS&lt;/span&gt; footprint, I&amp;#8217;ll strip those scripts out&amp;nbsp;of &lt;code&gt;base.html&lt;/code&gt; as a separate change — but the Molokai work doesn&amp;#8217;t depend on&amp;nbsp;it.&lt;/p&gt;
&lt;h2&gt;Making it&amp;nbsp;reusable&lt;/h2&gt;
&lt;p&gt;The molokai.css file in this post is a drop-in for anyone running the gum theme. Copy it&amp;nbsp;into &lt;code&gt;theme-gum/static/molokai.css&lt;/code&gt;,&amp;nbsp;set &lt;code&gt;CUSTOM_CSS_FILES = ['theme/molokai.css']&lt;/code&gt; in&amp;nbsp;your &lt;code&gt;pelicanconf.py&lt;/code&gt;, and you&amp;#8217;re done. The two upstream fixes (the column-grid math and the&amp;nbsp;regenerated &lt;code&gt;pygment.css&lt;/code&gt;) are independent of the palette and worth applying even if you&amp;#8217;d rather pick a different color&amp;nbsp;scheme.&lt;/p&gt;
&lt;p&gt;The full bundle — gum templates with the column fix, the&amp;nbsp;regenerated &lt;code&gt;pygment.css&lt;/code&gt;,&amp;nbsp;and &lt;code&gt;molokai.css&lt;/code&gt; — is published as a standalone theme repo at &lt;a href="https://gitlab.com/rubackedup-com/pelican-theme-gum-molokai"&gt;gitlab.com/rubackedup-com/pelican-theme-gum-molokai&lt;/a&gt;. &lt;span class="caps"&gt;MIT&lt;/span&gt; licensed, same as upstream gum. Clone it as&amp;nbsp;your &lt;code&gt;theme-gum/&lt;/code&gt; and you&amp;#8217;re done in two lines of&amp;nbsp;config.&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s next on this&amp;nbsp;blog&lt;/h2&gt;
&lt;p&gt;This is the first commit on a longer theme-refresh branch. Next on the&amp;nbsp;list:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Untrack &lt;code&gt;output/&lt;/code&gt; and &lt;code&gt;__pycache__/&lt;/code&gt; (legacy committed build&amp;nbsp;artifacts)&lt;/li&gt;
&lt;li&gt;Drop gum&amp;#8217;s&amp;nbsp;empty &lt;code&gt;Pages&lt;/code&gt; heading in the sidebar when there are no&amp;nbsp;pages&lt;/li&gt;
&lt;li&gt;Add OpenGraph and Twitter Card meta&amp;nbsp;to &lt;code&gt;base.html&lt;/code&gt; so link previews stop looking&amp;nbsp;awful&lt;/li&gt;
&lt;li&gt;Decide whether to strip the jQuery/Gumby &lt;span class="caps"&gt;JS&lt;/span&gt;&amp;nbsp;payload&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of those block the Molokai work, which is what I cared about&amp;nbsp;most.&lt;/p&gt;</content><category term="Technology"/><category term="pelican"/><category term="theme"/><category term="css"/><category term="molokai"/><category term="gum"/><category term="blog"/></entry><entry><title>falcon-stats: A Trading Discipline System Built on PAI</title><link href="https://davidduncan.org/falcon-stats-trading-discipline.html" rel="alternate"/><published>2026-04-27T18:00:00-05:00</published><updated>2026-04-27T18:00:00-05:00</updated><author><name>David Duncan</name></author><id>tag:davidduncan.org,2026-04-27:/falcon-stats-trading-discipline.html</id><summary type="html">&lt;p&gt;I am open-sourcing falcon-stats — a complete trading discipline system built on &lt;a href="https://danielmiessler.com"&gt;Daniel Miessler&lt;/a&gt;&amp;#8216;s &lt;a href="https://github.com/danielmiessler/Personal_AI_Infrastructure"&gt;&lt;span class="caps"&gt;PAI&lt;/span&gt;&lt;/a&gt; framework. It ingests your &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader data, calculates statistical covariance, scores your discipline, and tells you the truth about your trading. Here is why I built it and how you can use&amp;nbsp;it.&lt;/p&gt;</summary><content type="html">&lt;h1&gt;falcon-stats: A Trading Discipline System Built on &lt;span class="caps"&gt;PAI&lt;/span&gt;&lt;/h1&gt;
&lt;p&gt;I have been day trading for about 13 months. In that time I have taken 1,254 round-trips across 187 different stocks. And until two weeks ago, I had no idea what my actual numbers looked&amp;nbsp;like.&lt;/p&gt;
&lt;p&gt;Now I do. I built a system to tell me, and the answer was uncomfortable: I am running a negative expectancy of -0.79R per trade on average, despite winning 51% of my trading&amp;nbsp;days.&lt;/p&gt;
&lt;p&gt;Here is the thing — that is not a stock-picking problem. I win more days than I lose. The problem is behavioral: my average red day is 2.5 times the size of my average green day. I size up when I should size down. I grind 24 round-trips on &lt;span class="caps"&gt;AMD&lt;/span&gt; when I should take one clean setup and walk&amp;nbsp;away.&lt;/p&gt;
&lt;p&gt;I am a winning trader with a losing habit. And now I have the data to prove&amp;nbsp;it.&lt;/p&gt;
&lt;h2&gt;What falcon-stats&amp;nbsp;Does&lt;/h2&gt;
&lt;p&gt;falcon-stats is a Python package that turns your &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader exports and broker statements into honest, unflinching self-assessment. It is built on &lt;a href="https://danielmiessler.com"&gt;Daniel Miessler&lt;/a&gt;&amp;#8216;s &lt;a href="https://danielmiessler.com/blog/personal-ai-infrastructure"&gt;&lt;span class="caps"&gt;PAI&lt;/span&gt; (Personal &lt;span class="caps"&gt;AI&lt;/span&gt; Infrastructure)&lt;/a&gt; framework, and it uses &lt;a href="https://danielmiessler.com/telos/"&gt;&lt;span class="caps"&gt;TELOS&lt;/span&gt;&lt;/a&gt; — the life operating system from &lt;span class="caps"&gt;PAI&lt;/span&gt; — to connect your trading performance to your personal goals, challenges, and&amp;nbsp;strategies.&lt;/p&gt;
&lt;p&gt;Here is what it&amp;nbsp;does:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ingests your trades.&lt;/strong&gt; It reads &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader &lt;span class="caps"&gt;CSV&lt;/span&gt; exports and Cobra Trading broker Excel statements, groups individual executions into round-trips (handling scaling in, partial fills, and multiple positions per symbol per day), and computes R-multiples from your planned&amp;nbsp;stops.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Calculates your real numbers.&lt;/strong&gt; Win rate, expectancy, profit factor, max drawdown, R-multiple distribution, and streak tracking. Not from a sample of your best days — from every trade you have ever&amp;nbsp;taken.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scores your discipline.&lt;/strong&gt; Each trading day gets a discipline score from 1 to 10 based on trade count, R-asymmetry (are your winners bigger than your losers?), and process adherence. Green means you traded well (7 or higher). Red means you did not. The color has nothing to do with whether you made&amp;nbsp;money.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Identifies your patterns.&lt;/strong&gt; Which tickers are you trading the most? Which ones are costing you money despite high win rates? My data showed that &lt;span class="caps"&gt;AMD&lt;/span&gt; — a stock I win 69% of the time — has a deeply negative R-expectancy because the 31% I lose are five times bigger than the 69% I win. &lt;span class="caps"&gt;AMD&lt;/span&gt; is now banned from my live account until I prove edge in&amp;nbsp;simulation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Runs statistical covariance.&lt;/strong&gt; Before I trade any stock, I pull 90 days of daily price data from Polygon and calculate the z-score — how far the current price is from its 20-day mean in standard deviations. Stocks in normal range get my Fashionably Late long setups. Stocks at statistical extremes get Offsides short setups. The math tells me which direction to trade instead of my&amp;nbsp;gut.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Estimates costs.&lt;/strong&gt; A trade cost calculator uses my actual Cobra broker fee data from 847 executions to estimate commissions, &lt;span class="caps"&gt;ECN&lt;/span&gt; fees, &lt;span class="caps"&gt;SEC&lt;/span&gt; fees, and breakeven move for any planned trade. Spoiler: fees are negligible relative to the R-multiple on most trades. The problem is not costs. It is&amp;nbsp;behavior.&lt;/p&gt;
&lt;h2&gt;The&amp;nbsp;Architecture&lt;/h2&gt;
&lt;p&gt;DynamoDB is the source of truth for all trading data. Not Notion. Not a spreadsheet.&amp;nbsp;DynamoDB.&lt;/p&gt;
&lt;p&gt;I learned this the hard way when I accidentally deleted my Notion databases. If your source of truth is a SaaS product you do not control, you do not have a source of truth. Now Notion is a rebuildable view — if it disappears, I recreate it from DynamoDB in&amp;nbsp;minutes.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;DAS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;CSV&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;falcon&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;stats&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;--&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;DynamoDB&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;of&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;truth&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                                &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="w"&gt;                                &lt;/span&gt;&lt;span class="o"&gt;+-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Notion&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rebuildable&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;view&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                                &lt;/span&gt;&lt;span class="o"&gt;+-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Slack&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;discipline&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="w"&gt;                                &lt;/span&gt;&lt;span class="o"&gt;+-&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;Substrate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;historical&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kr"&gt;CSV&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The system is designed with extension points. If you use Interactive Brokers instead of Cobra, you write one parser class. If you prefer PostgreSQL over DynamoDB, you implement one database interface. Notion, Obsidian, plain markdown — swap the publisher. The core engine does not care where the data comes from or where it&amp;nbsp;goes.&lt;/p&gt;
&lt;h2&gt;How &lt;span class="caps"&gt;PAI&lt;/span&gt; and &lt;span class="caps"&gt;TELOS&lt;/span&gt; Make This&amp;nbsp;Work&lt;/h2&gt;
&lt;p&gt;falcon-stats is not just a statistics engine. It is integrated into a complete Personal &lt;span class="caps"&gt;AI&lt;/span&gt; Infrastructure that&amp;nbsp;includes:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Morning Game Plans.&lt;/strong&gt; Every trading day at 4:30 &lt;span class="caps"&gt;AM&lt;/span&gt;, an automated agent scans pre-market gappers, calculates z-scores, filters for my account size, and publishes a watchlist to Notion and Slack with specific Fashionably Late and Offsides Reversal entry scenarios. I wake up to a game plan I did not have to build&amp;nbsp;manually.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Daily Reviews.&lt;/strong&gt; After each session, I ingest my trades and get a discipline-graded report card. Did I follow the game plan? Did I honor stops? Did I trade outside my restriction list? The system knows my active behavioral challenges (revenge trading, inverse sizing) and checks for&amp;nbsp;them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Weekly Readiness Reviews.&lt;/strong&gt; Every Sunday evening, the system pulls previous week earnings results, coming week catalysts, YouTube intel from my trusted channels, Substrate macro data, and my personal trading statistics. It publishes a strategic prep document with chart walkthrough narratives that I can record as video&amp;nbsp;content.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;TELOS&lt;/span&gt; Integration.&lt;/strong&gt; My trading goals, challenges, strategies, and lessons learned are all tracked in &lt;a href="https://danielmiessler.com/telos/"&gt;&lt;span class="caps"&gt;TELOS&lt;/span&gt;&lt;/a&gt; — &lt;span class="caps"&gt;PAI&lt;/span&gt;&amp;#8217;s life operating system. When I discover that my top 5 losing tickers account for 79% of my total losses, that lesson gets captured in &lt;span class="caps"&gt;TELOS&lt;/span&gt; and referenced in every future game plan. The system learns because I&amp;nbsp;learn.&lt;/p&gt;
&lt;h2&gt;The Philosophy: P&amp;amp;L Over Price&amp;nbsp;Action&lt;/h2&gt;
&lt;p&gt;I was trading 24 round-trips on &lt;span class="caps"&gt;AMD&lt;/span&gt; in a single session with a 64% win rate and still losing money. My &lt;span class="caps"&gt;AI&lt;/span&gt; partner said something that changed my thinking: &amp;#8220;You are watching the price action instead of managing your P&amp;amp;L. Focus on the R-multiple you are capturing, not the number of trades you are&amp;nbsp;taking.&amp;#8221;&lt;/p&gt;
&lt;p&gt;One trade at 2R is worth more than twenty trades at 0.1R. The math is&amp;nbsp;simple:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One trade per day targeting 2R with a 50% win rate = +0.5R expected value per&amp;nbsp;trade&lt;/li&gt;
&lt;li&gt;That flips the expectancy from -0.79R to +0.5R per&amp;nbsp;trade&lt;/li&gt;
&lt;li&gt;Over 20 trading days per month, the R-curve goes from declining to&amp;nbsp;compounding&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The entire system — the covariance analysis, the discipline scoring, the restriction list, the one-trade commitment — exists to enforce this insight. Order flow first, then price action, but always manage to the P&amp;amp;L. Fewer trades, better&amp;nbsp;R-multiples.&lt;/p&gt;
&lt;h2&gt;Who This Is&amp;nbsp;For&lt;/h2&gt;
&lt;p&gt;This is specifically built for &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader and Cobra Trading customers who are willing to store their data in DynamoDB. That is a narrow audience. But the architecture is modular — with a little work, you can adapt it to Interactive Brokers, &lt;span class="caps"&gt;TWS&lt;/span&gt; Gateway, or any broker that exports trade data. You can swap DynamoDB for Google BigTable, PostgreSQL, or&amp;nbsp;SQLite.&lt;/p&gt;
&lt;p&gt;More broadly, this is for anyone in &lt;a href="https://danielmiessler.com"&gt;Daniel&amp;#8217;s &lt;span class="caps"&gt;PAI&lt;/span&gt; community&lt;/a&gt; who wants to see how &lt;span class="caps"&gt;TELOS&lt;/span&gt; and &lt;span class="caps"&gt;PAI&lt;/span&gt; can be applied to a performance discipline. The pattern works for trading, but it works for anything that requires deliberate practice and honest&amp;nbsp;self-assessment.&lt;/p&gt;
&lt;p&gt;If you want to share your progress with a mentor, a coach, or a prospective employer, this system produces the documentation automatically. The discipline scores, the statistical analysis, the data-backed strategy evolution — it is all there, updated daily, backed by real&amp;nbsp;data.&lt;/p&gt;
&lt;h2&gt;Getting&amp;nbsp;Started&lt;/h2&gt;
&lt;p&gt;The repository is at &lt;a href="https://github.com/davdunc/falcon-stats"&gt;github.com/davdunc/falcon-stats&lt;/a&gt;. The &lt;span class="caps"&gt;README&lt;/span&gt; has setup instructions for &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader + Cobra + &lt;span class="caps"&gt;AWS&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;If you are using &lt;span class="caps"&gt;PAI&lt;/span&gt;, the Trading skill templates are designed to drop into&amp;nbsp;your &lt;code&gt;~/.claude/skills/&lt;/code&gt; directory. Customize the playbook setups, add your own YouTube channels, set your account size constraints, and the system adapts to your&amp;nbsp;trading.&lt;/p&gt;
&lt;h2&gt;Acknowledgments&lt;/h2&gt;
&lt;p&gt;This system would not exist without &lt;a href="https://danielmiessler.com"&gt;Daniel Miessler&lt;/a&gt;&amp;#8216;s &lt;a href="https://github.com/danielmiessler/Personal_AI_Infrastructure"&gt;&lt;span class="caps"&gt;PAI&lt;/span&gt;&lt;/a&gt; framework. The Algorithm, the skill system, &lt;span class="caps"&gt;TELOS&lt;/span&gt;, the memory architecture — Daniel designed all of it and &lt;a href="https://github.com/danielmiessler/Personal_AI_Infrastructure"&gt;open-sourced it generously&lt;/a&gt;. I forked it and rebuilt it for my own mission, and now I am sharing what I built on top of&amp;nbsp;it.&lt;/p&gt;
&lt;p&gt;Thanks also to James Diamont for the coaching that helped me see the patterns in my trading before the data confirmed them. And to the &lt;span class="caps"&gt;SMB&lt;/span&gt; Capital team, whose PlayBook methodology and Fashionably Late / Offsides scalp frameworks gave me the specific setups to build a systematic approach&amp;nbsp;around.&lt;/p&gt;
&lt;p&gt;The numbers are not where I want them yet. But for the first time, I can see exactly what needs to change, I have the tools to measure whether it is working, and I have an &lt;span class="caps"&gt;AI&lt;/span&gt; partner that remembers everything and never lets me pretend the data says something it does&amp;nbsp;not.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;David Duncan is a momentum trader, Fedora Cloud &lt;span class="caps"&gt;SIG&lt;/span&gt; contributor, and builder of &lt;span class="caps"&gt;AI&lt;/span&gt;-assisted trading infrastructure at &lt;a href="https://www.davidduncan.org"&gt;davidduncan.org&lt;/a&gt;. The falcon-stats source code is available at &lt;a href="https://github.com/davdunc/falcon-stats"&gt;github.com/davdunc/falcon-stats&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content><category term="Technology"/><category term="AI"/><category term="Trading"/><category term="Python"/><category term="PAI"/><category term="Open Source"/><category term="TELOS"/><category term="DynamoDB"/></entry><entry><title>Building a Bookmap-Style CVD Indicator with Claude Code and Python</title><link href="https://davidduncan.org/cvd-indicator-bookmap.html" rel="alternate"/><published>2026-04-18T07:00:00-05:00</published><updated>2026-04-18T07:00:00-05:00</updated><author><name>David Duncan</name></author><id>tag:davidduncan.org,2026-04-18:/cvd-indicator-bookmap.html</id><summary type="html">&lt;p&gt;Exploring how to build a Cumulative Volume Delta indicator and compact order flow visualization using &lt;span class="caps"&gt;IBKR&lt;/span&gt; tick data, Python, and modern charting libraries — with Claude as a development&amp;nbsp;partner.&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Building a Bookmap-Style &lt;span class="caps"&gt;CVD&lt;/span&gt; Indicator with Claude Code and&amp;nbsp;Python&lt;/h1&gt;
&lt;p&gt;I had a conversation recently with prahko from &lt;span class="caps"&gt;SMB&lt;/span&gt; Capital about building order flow visualization tools. He built a Cumulative Volume Delta (&lt;span class="caps"&gt;CVD&lt;/span&gt;) widget using the &lt;span class="caps"&gt;IBKR&lt;/span&gt; &lt;span class="caps"&gt;TWS&lt;/span&gt; Gateway, and it got me thinking: why am I paying for Bookmap when I could build exactly the indicator I need, tuned to my trading style, using tools I already&amp;nbsp;have?&lt;/p&gt;
&lt;h2&gt;What &lt;span class="caps"&gt;CVD&lt;/span&gt; Actually&amp;nbsp;Is&lt;/h2&gt;
&lt;p&gt;Cumulative Volume Delta is one of the clearest windows into market microstructure. The concept is simple: for every trade that executes, classify it as buying pressure (executed at the ask) or selling pressure (executed at the bid). Accumulate the difference over&amp;nbsp;time.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;CVD = cumulative_sum(buy_volume - sell_volume)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;When &lt;span class="caps"&gt;CVD&lt;/span&gt; trends up, aggressive buyers are in control. When it trends down, sellers are dominant. The divergences between &lt;span class="caps"&gt;CVD&lt;/span&gt; and price are where the real edge lives — price making new highs while &lt;span class="caps"&gt;CVD&lt;/span&gt; makes lower highs signals exhaustion. That is the kind of systematic, quantifiable signal that appeals to me as a trader moving toward algorithmic&amp;nbsp;execution.&lt;/p&gt;
&lt;h2&gt;The Data&amp;nbsp;Pipeline&lt;/h2&gt;
&lt;p&gt;I already have the pieces. My Falcon trading platform includes a headless Interactive Brokers gateway, and the &lt;span class="caps"&gt;IBKR&lt;/span&gt; &lt;span class="caps"&gt;TWS&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt; provides tick-by-tick trade data with aggressor side classification. The architecture would&amp;nbsp;be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;IBKR TWS Gateway
    |
    v
Python (ib_async) — reqTickByTickData(&amp;quot;AllLast&amp;quot;)
    |  classify: executed at ask = buy, at bid = sell
    |  compute: CVD = cumsum(buy_vol - sell_vol)
    v
FastAPI + WebSocket (/ws/cvd)
    |
    v
Browser widget (compact, embeddable)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The Python layer handles the computation. A lightweight WebSocket endpoint pushes updates to a browser-based chart. The question is what to render&amp;nbsp;with.&lt;/p&gt;
&lt;h2&gt;Choosing a Visualization&amp;nbsp;Library&lt;/h2&gt;
&lt;p&gt;I researched several options for rendering compact, real-time financial charts. Here is what I&amp;nbsp;found.&lt;/p&gt;
&lt;h3&gt;D3.js — Maximum Flexibility, Maximum&amp;nbsp;Effort&lt;/h3&gt;
&lt;p&gt;D3 is the Swiss army knife of data visualization. You can build literally anything. The problem is you have to build literally everything. For a single-purpose &lt;span class="caps"&gt;CVD&lt;/span&gt; widget, D3 is the wrong tool — its learning curve and manual update management are not justified when purpose-built financial charting libraries exist. The d3fc financial components library helps, but it is still fundamentally a general-purpose&amp;nbsp;framework.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Skip for this use&amp;nbsp;case.&lt;/p&gt;
&lt;h3&gt;Lightweight Charts (TradingView) — The Sweet&amp;nbsp;Spot&lt;/h3&gt;
&lt;p&gt;TradingView open-sourced their charting library under Apache 2.0. It is purpose-built for compact financial chart embeds at under &lt;span class="caps"&gt;50KB&lt;/span&gt; gzipped. The &lt;span class="caps"&gt;API&lt;/span&gt; is familiar to anyone who has used TradingView, and it includes a Custom Series plugin &lt;span class="caps"&gt;API&lt;/span&gt; that supports building a &lt;span class="caps"&gt;CVD&lt;/span&gt; renderer with custom Canvas&amp;nbsp;drawing.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;update()&lt;/code&gt; method handles real-time data pushes efficiently, and the look and feel is professional out of the box. For a &lt;span class="caps"&gt;CVD&lt;/span&gt; line chart alongside price, this is the natural&amp;nbsp;choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Production widget. Best balance of capability, size, and&amp;nbsp;polish.&lt;/p&gt;
&lt;h3&gt;Plotly and Dash — Python-Native&amp;nbsp;Prototyping&lt;/h3&gt;
&lt;p&gt;Dash lets you build the entire visualization in Python without touching JavaScript.&amp;nbsp;Use &lt;code&gt;dcc.Graph&lt;/code&gt; with &lt;code&gt;dcc.Interval&lt;/code&gt; for periodic refresh. This is the fastest path to validating the indicator logic and data pipeline from &lt;span class="caps"&gt;IBKR&lt;/span&gt;.&lt;/p&gt;
&lt;p&gt;The limitation is performance — Dash callbacks add latency, and Plotly.js weighs about &lt;span class="caps"&gt;3MB&lt;/span&gt;. It will not handle sub-second updates smoothly. But for proving the concept in an afternoon, nothing is&amp;nbsp;faster.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Prototype only. Validate the math, then move to Lightweight&amp;nbsp;Charts.&lt;/p&gt;
&lt;h3&gt;uPlot — Raw&amp;nbsp;Performance&lt;/h3&gt;
&lt;p&gt;At &lt;span class="caps"&gt;45KB&lt;/span&gt;, uPlot is the smallest and fastest open-source charting option. It handles 60fps streaming at 10 percent &lt;span class="caps"&gt;CPU&lt;/span&gt;. If Lightweight Charts cannot keep up with 1000+ ticks per second rendering, uPlot is the fallback. The tradeoff is a more utilitarian look and sparser&amp;nbsp;documentation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Performance fallback if&amp;nbsp;needed.&lt;/p&gt;
&lt;h3&gt;SciChart.js — Enterprise&amp;nbsp;Grade&lt;/h3&gt;
&lt;p&gt;SciChart uses WebGL and WebAssembly to render 40 million data points per second. This is what you would use if building a full Bookmap-style Level 2 heatmap alongside &lt;span class="caps"&gt;CVD&lt;/span&gt;. For just a &lt;span class="caps"&gt;CVD&lt;/span&gt; line, it is overkill — and the commercial license starts at $500 per&amp;nbsp;year.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Verdict:&lt;/strong&gt; Only if building the full&amp;nbsp;heatmap.&lt;/p&gt;
&lt;h2&gt;What Makes Bookmap&amp;nbsp;Special&lt;/h2&gt;
&lt;p&gt;Bookmap itself is a Java and OpenGL application rendering at 40 &lt;span class="caps"&gt;FPS&lt;/span&gt;. Its technical moat is not the &lt;span class="caps"&gt;CVD&lt;/span&gt; indicator — that is a simple cumulative sum. The moat is the full Level 2 order book heatmap with historical replay, which requires ingesting and rendering millions of price-level updates per second. Color intensity maps to limit order depth: red and orange for high liquidity, blue and green for&amp;nbsp;low.&lt;/p&gt;
&lt;p&gt;For a standalone &lt;span class="caps"&gt;CVD&lt;/span&gt; widget, I do not need anywhere near that complexity. A cumulative line chart with divergence markers against price is sufficient to capture the signal I am looking&amp;nbsp;for.&lt;/p&gt;
&lt;h2&gt;Where Claude Fits&amp;nbsp;In&lt;/h2&gt;
&lt;p&gt;This is the kind of project where having an &lt;span class="caps"&gt;AI&lt;/span&gt; development partner changes the economics. Claude Code is effective at iterating on Lightweight Charts plugins because the &lt;span class="caps"&gt;API&lt;/span&gt; surface is small enough to fit in context, the Custom Series interface is a well-defined contract, and you can test changes by refreshing a single &lt;span class="caps"&gt;HTML&lt;/span&gt;&amp;nbsp;file.&lt;/p&gt;
&lt;p&gt;The pattern I have been using: describe the visual I want, let Claude generate the plugin class and &lt;span class="caps"&gt;HTML&lt;/span&gt; harness, then iterate on rendering details. The feedback loop is minutes, not hours. For a systematic trader who wants custom indicators without becoming a full-time frontend developer, this is the right&amp;nbsp;approach.&lt;/p&gt;
&lt;h2&gt;Next&amp;nbsp;Steps&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Prototype&lt;/strong&gt; — Python &lt;span class="caps"&gt;CVD&lt;/span&gt; computation from &lt;span class="caps"&gt;IBKR&lt;/span&gt; tick data using Plotly and Dash. Validate the math against known &lt;span class="caps"&gt;CVD&lt;/span&gt;&amp;nbsp;implementations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Widget&lt;/strong&gt; — Lightweight Charts Custom Series plugin for the &lt;span class="caps"&gt;CVD&lt;/span&gt; line. Compact, embeddable, real-time via&amp;nbsp;WebSocket.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration&lt;/strong&gt; — Wire into the Falcon platform alongside the morning game plan pipeline and trading&amp;nbsp;log.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The goal is not to rebuild Bookmap. It is to build the specific order flow indicator I need, own the data pipeline end to end, and have a tool that evolves with my trading — because I built&amp;nbsp;it.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;David Duncan is a momentum trader, Fedora Cloud &lt;span class="caps"&gt;SIG&lt;/span&gt; contributor, and builder of &lt;span class="caps"&gt;AI&lt;/span&gt;-assisted trading infrastructure at &lt;a href="https://www.davidduncan.org"&gt;davidduncan.org&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content><category term="Technology"/><category term="AI"/><category term="Trading"/><category term="Python"/><category term="Order Flow"/><category term="Visualization"/><category term="Claude Code"/></entry><entry><title>PAI Framework: How I Rebuilt a Personal AI Infrastructure for Trading and Cloud Work</title><link href="https://davidduncan.org/pai-framework.html" rel="alternate"/><published>2026-04-16T16:30:00-05:00</published><updated>2026-04-16T16:30:00-05:00</updated><author><name>David Duncan</name></author><id>tag:davidduncan.org,2026-04-16:/pai-framework.html</id><summary type="html">&lt;p&gt;I forked Daniel s open-source &lt;span class="caps"&gt;PAI&lt;/span&gt; framework and rebuilt it around my mission — systematic trading, Fedora Cloud infrastructure, and building an &lt;span class="caps"&gt;AI&lt;/span&gt; partnership that grows with&amp;nbsp;me.&lt;/p&gt;</summary><content type="html">&lt;h1&gt;&lt;span class="caps"&gt;PAI&lt;/span&gt; Framework: How I Rebuilt a Personal &lt;span class="caps"&gt;AI&lt;/span&gt; Infrastructure for Trading and Cloud&amp;nbsp;Work&lt;/h1&gt;
&lt;p&gt;A few months ago I discovered &lt;span class="caps"&gt;PAI&lt;/span&gt; — Personal &lt;span class="caps"&gt;AI&lt;/span&gt; Infrastructure — an open-source framework built by Daniel that turns &lt;a href="https://claude.ai/claude-code"&gt;Claude Code&lt;/a&gt; into a persistent, skill-based &lt;span class="caps"&gt;AI&lt;/span&gt; system. I forked it and have been rebuilding it around my own mission ever&amp;nbsp;since.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;My fork:&lt;/strong&gt; &lt;a href="https://github.com/davdunc/pai-framework"&gt;github.com/davdunc/pai-framework&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;What Drew Me to &lt;span class="caps"&gt;PAI&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;I was already using Claude Code daily, but every conversation started from scratch. No memory of what I was working on, what I had tried before, or what I had learned. &lt;span class="caps"&gt;PAI&lt;/span&gt; solved that with an architecture I immediately&amp;nbsp;respected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Algorithm&lt;/strong&gt; — A structured 7-phase execution framework (Observe, Think, Plan, Build, Execute, Verify, Learn) that produces verifiable outcomes. Every task generates Ideal State Criteria and tracks progress. This alone changed how I approach complex&amp;nbsp;work.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt; — Modular capability packages with workflows and routing&amp;nbsp;logic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hooks&lt;/strong&gt; — Lifecycle event handlers that fire on tool use, session events, and context&amp;nbsp;management.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Memory&lt;/strong&gt; — A persistent file-based system that carries context across&amp;nbsp;conversations.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;span class="caps"&gt;TELOS&lt;/span&gt;&lt;/strong&gt; — A life operating system for goals, projects, and challenges that personalizes every&amp;nbsp;interaction.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Daniel open-sourced all of this. I am grateful for the work and the generosity of sharing&amp;nbsp;it.&lt;/p&gt;
&lt;h2&gt;How I Made It&amp;nbsp;Mine&lt;/h2&gt;
&lt;p&gt;The original &lt;span class="caps"&gt;PAI&lt;/span&gt; had skills for &lt;span class="caps"&gt;OSINT&lt;/span&gt; investigations, security pentesting, visual content creation, and podcast editing. None of that is my work. I stripped it down and rebuilt around three&amp;nbsp;pillars:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Systematic Trading (Primary Mission)&lt;/strong&gt;
I am working toward consistent profitability as a momentum day trader, with a goal of transitioning to fully systematic, algorithmic execution. &lt;span class="caps"&gt;PAI&lt;/span&gt; now powers my morning game plans, market research, trade review, and discipline tracking. I am building a platform called Falcon that bridges &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader with Python automation — and &lt;span class="caps"&gt;PAI&lt;/span&gt; is becoming the intelligence&amp;nbsp;layer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Fedora Cloud &lt;span class="caps"&gt;SIG&lt;/span&gt; (Community Work)&lt;/strong&gt;
I contribute to Fedora Cloud images and bootable containers. &lt;span class="caps"&gt;PAI&lt;/span&gt; helps me manage community coordination, technical documentation, and release&amp;nbsp;preparation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Bridge Between Them&lt;/strong&gt;
Falcon validates cloud-native infrastructure patterns (Podman, Quadlets, bootable containers) while simultaneously generating trading income. The infrastructure work proves the &lt;span class="caps"&gt;OS&lt;/span&gt; patterns. The trading funds the time for community&amp;nbsp;work.&lt;/p&gt;
&lt;h2&gt;What the Fork Looks&amp;nbsp;Like&lt;/h2&gt;
&lt;p&gt;I audited every component against my actual&amp;nbsp;needs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Kept:&lt;/strong&gt; Trading, Research, Thinking (FirstPrinciples, Council debates), &lt;span class="caps"&gt;TELOS&lt;/span&gt;, Agents, Economic Metrics, and core&amp;nbsp;utilities&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Archived:&lt;/strong&gt; 10 skills and sub-skills that served someone else s&amp;nbsp;mission&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Added:&lt;/strong&gt; PreCompact hooks for context preservation, Elicitation hooks for &lt;span class="caps"&gt;MCP&lt;/span&gt; automation, mandatory prerequisite checks in the&amp;nbsp;Algorithm&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Building next:&lt;/strong&gt; FedoraCloud skill, Falcon platform skill, &lt;span class="caps"&gt;DAS&lt;/span&gt; Trader &lt;span class="caps"&gt;CMD&lt;/span&gt; &lt;span class="caps"&gt;API&lt;/span&gt;&amp;nbsp;integration&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The result is a leaner system that routes more accurately to what I actually&amp;nbsp;do.&lt;/p&gt;
&lt;h2&gt;What I Have&amp;nbsp;Learned&lt;/h2&gt;
&lt;p&gt;The most valuable thing about &lt;span class="caps"&gt;PAI&lt;/span&gt; is not the code — it is the philosophy. The idea that your &lt;span class="caps"&gt;AI&lt;/span&gt; assistant should know who you are, what you are working toward, and what you have learned from past mistakes. My &lt;span class="caps"&gt;PAI&lt;/span&gt; knows my trading rules, my risk tolerance, my behavioral patterns I am trying to fix, and my long-term goals. That context makes every interaction more useful than starting from&amp;nbsp;zero.&lt;/p&gt;
&lt;p&gt;I am also learning that the best tools for a systematic trader are not the same as the best tools for a discretionary one. My &lt;span class="caps"&gt;PAI&lt;/span&gt; is evolving toward quantitative approaches — backtested setups, algorithmic execution, math-grounded decisions. That is the trader I want to become, and having an &lt;span class="caps"&gt;AI&lt;/span&gt; partner that remembers that aspiration helps me stay on&amp;nbsp;track.&lt;/p&gt;
&lt;h2&gt;Try It&amp;nbsp;Yourself&lt;/h2&gt;
&lt;p&gt;If you use Claude Code and want persistent&amp;nbsp;context:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Check out Daniel s original work or &lt;a href="https://github.com/davdunc/pai-framework"&gt;my&amp;nbsp;fork&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Copy the framework&amp;nbsp;to &lt;code&gt;~/.claude/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create your&amp;nbsp;own &lt;code&gt;PAI/USER/&lt;/code&gt; directory with your goals and&amp;nbsp;projects&lt;/li&gt;
&lt;li&gt;Start a conversation — the mode system kicks in&amp;nbsp;automatically&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The framework is a starting point. The value comes from making it&amp;nbsp;yours.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;David Duncan is a momentum trader, Fedora Cloud &lt;span class="caps"&gt;SIG&lt;/span&gt; contributor, and builder of &lt;span class="caps"&gt;AI&lt;/span&gt;-assisted infrastructure at &lt;a href="https://www.davidduncan.org"&gt;davidduncan.org&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content><category term="Technology"/><category term="AI"/><category term="Claude Code"/><category term="PAI"/><category term="Infrastructure"/><category term="Open Source"/></entry><entry><title>Introducing The Consilium: A Personal AI Advisory System</title><link href="https://davidduncan.org/consilium-introduction.html" rel="alternate"/><published>2025-08-06T12:00:00-05:00</published><updated>2025-08-06T17:25:00-05:00</updated><author><name>David Duncan</name></author><id>tag:davidduncan.org,2025-08-06:/consilium-introduction.html</id><summary type="html">&lt;p&gt;Beginning a journey to build &amp;#8220;The Consilium&amp;#8221; - a multi-agent &lt;span class="caps"&gt;AI&lt;/span&gt; advisory system for personal life management, built on cost-effective Red Hat/&lt;span class="caps"&gt;AWS&lt;/span&gt;&amp;nbsp;infrastructure.&lt;/p&gt;</summary><content type="html">&lt;h1&gt;Introducing The Consilium: A Personal &lt;span class="caps"&gt;AI&lt;/span&gt; Advisory&amp;nbsp;System&lt;/h1&gt;
&lt;p&gt;&lt;em&gt;Update: GitLab &lt;span class="caps"&gt;CI&lt;/span&gt;/&lt;span class="caps"&gt;CD&lt;/span&gt; pipeline now configured for automated deployments with &lt;span class="caps"&gt;IAM&lt;/span&gt; roles!&amp;nbsp;🚀&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m embarking on what might be my most interesting personal project yet: building &amp;#8220;The Consilium&amp;#8221; - a multi-agent &lt;span class="caps"&gt;AI&lt;/span&gt; advisory system that acts as my personal council of specialists. Think of it as having a team of &lt;span class="caps"&gt;AI&lt;/span&gt; advisors, each expert in different aspects of life&amp;nbsp;management.&lt;/p&gt;
&lt;h2&gt;Why &amp;#8220;The&amp;nbsp;Consilium&amp;#8221;?&lt;/h2&gt;
&lt;p&gt;The name comes from the Latin term for an advisory council - historically used by Roman emperors for their trusted advisors. It perfectly captures what I&amp;#8217;m building: a council of &lt;span class="caps"&gt;AI&lt;/span&gt; agents, each specialized in different domains of personal&amp;nbsp;life.&lt;/p&gt;
&lt;h2&gt;The Agent&amp;nbsp;Council&lt;/h2&gt;
&lt;p&gt;My planned specialists&amp;nbsp;include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Financial Advisor&lt;/strong&gt;: Insurance policies, housing decisions, investment&amp;nbsp;tracking&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Location Intelligence&lt;/strong&gt;: Neighborhood data, local services, property&amp;nbsp;values  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Travel Coordinator&lt;/strong&gt;: Flight tracking, travel planning, loyalty program&amp;nbsp;optimization&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Environmental Monitor&lt;/strong&gt;: Weather patterns, seasonal planning, local&amp;nbsp;conditions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Health &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; Wellness&lt;/strong&gt;: Appointment scheduling, health metrics, preventive care&amp;nbsp;reminders&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Master Coordinator&lt;/strong&gt;: Routes queries between agents and synthesizes comprehensive&amp;nbsp;responses&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Technical Philosophy: Frugal over&amp;nbsp;Fast&lt;/h2&gt;
&lt;p&gt;This isn&amp;#8217;t about bleeding-edge performance or enterprise-scale infrastructure. It&amp;#8217;s about building cost-effective, privacy-first personal &lt;span class="caps"&gt;AI&lt;/span&gt;&amp;nbsp;infrastructure:&lt;/p&gt;
&lt;h3&gt;Key Design&amp;nbsp;Principles&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Local Model Serving&lt;/strong&gt;: Using &lt;a href="https://github.com/containers/ramalama"&gt;ramalama&lt;/a&gt; on Fedora instances for cost&amp;nbsp;control&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;span class="caps"&gt;AWS&lt;/span&gt; us-east-2&lt;/strong&gt;: Keeping costs low by avoiding premium&amp;nbsp;regions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Red Hat Ansible&lt;/strong&gt;: Infrastructure as code for reproducibility and&amp;nbsp;documentation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spot Instances&lt;/strong&gt;: Targeting 60-90% cost savings over on-demand&amp;nbsp;pricing&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacy-First&lt;/strong&gt;: All processing happens on my own &lt;span class="caps"&gt;AWS&lt;/span&gt;&amp;nbsp;infrastructure&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Estimated&amp;nbsp;Costs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phase 1 (Single Instance)&lt;/strong&gt;:&amp;nbsp;$15-30/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Phase 2 (Full Council)&lt;/strong&gt;: $50-80/month with Spot&amp;nbsp;instances&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data &lt;span class="amp"&gt;&amp;amp;&lt;/span&gt; Storage&lt;/strong&gt;: $5-10/month for logs and model&amp;nbsp;caching&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Architecture&amp;nbsp;Vision&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Financial     │    │    Location     │    │     Travel      │
│    Advisor      │    │  Intelligence   │    │  Coordinator    │
│                 │    │                 │    │                 │
│  ramalama +     │    │  ramalama +     │    │  ramalama +     │
│  Llama 3.2 3B   │    │  Llama 3.2 3B   │    │  Llama 3.2 3B   │
└─────────────────┘    └─────────────────┘    └─────────────────┘
         │                       │                       │
         └───────────────────────┼───────────────────────┘
                                 │
                    ┌─────────────────┐
                    │     Master      │
                    │  Coordinator    │
                    │                 │
                    │  Query Router   │
                    │  &amp;amp; Synthesizer  │
                    └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Why Build&amp;nbsp;This?&lt;/h2&gt;
&lt;p&gt;Personal &lt;span class="caps"&gt;AI&lt;/span&gt; infrastructure is becoming more accessible, but most examples focus on enterprise use cases or expensive cloud &lt;span class="caps"&gt;AI&lt;/span&gt; services. I want to demonstrate how individuals can build sophisticated, cost-effective &lt;span class="caps"&gt;AI&lt;/span&gt; systems for personal use while maintaining complete privacy and&amp;nbsp;control.&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s also something poetic about documenting the building of an &lt;span class="caps"&gt;AI&lt;/span&gt; system that will eventually help manage the very blog posts documenting its&amp;nbsp;creation.&lt;/p&gt;
&lt;h2&gt;The Journey&amp;nbsp;Ahead&lt;/h2&gt;
&lt;p&gt;I&amp;#8217;ll be documenting this entire build process here - the successes, failures, cost optimizations, and lessons learned. This is as much about the learning journey as the&amp;nbsp;destination.&lt;/p&gt;
&lt;h3&gt;Planned Blog&amp;nbsp;Series&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Setting Up the Foundation&lt;/strong&gt; - &lt;span class="caps"&gt;AWS&lt;/span&gt; infrastructure with&amp;nbsp;Ansible&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploying ramalama&lt;/strong&gt; - Local model serving on Fedora&amp;nbsp;instances  &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Building the First Agent&lt;/strong&gt; - Financial advisor&amp;nbsp;implementation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Communication&lt;/strong&gt; - Inter-agent protocols and&amp;nbsp;coordination&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost Optimization Deep Dive&lt;/strong&gt; - Keeping it frugal with Spot&amp;nbsp;instances&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security and Privacy&lt;/strong&gt; - Protecting personal data in the&amp;nbsp;cloud&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lessons Learned&lt;/strong&gt; - What worked, what didn&amp;#8217;t, what I&amp;#8217;d do&amp;nbsp;differently&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Getting&amp;nbsp;Started&lt;/h2&gt;
&lt;p&gt;The project is already underway with a proper directory structure, Ansible playbooks, and deployment guides. Everything is designed to be reproducible and&amp;nbsp;well-documented.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re interested in following along or building something similar, the entire project will be documented with infrastructure-as-code principles. While I won&amp;#8217;t be open-sourcing the personal configuration details, the architectural patterns and deployment strategies will be fully&amp;nbsp;shared.&lt;/p&gt;
&lt;h2&gt;What&amp;#8217;s&amp;nbsp;Next?&lt;/h2&gt;
&lt;p&gt;Next up: Setting up the foundational &lt;span class="caps"&gt;AWS&lt;/span&gt; infrastructure in us-east-2 and getting our first ramalama instance running. The Consilium&amp;#8217;s first advisor is about to come&amp;nbsp;online.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Follow along as I build The Consilium - proving that personal &lt;span class="caps"&gt;AI&lt;/span&gt; infrastructure can be both sophisticated and&amp;nbsp;affordable.&lt;/em&gt;&lt;/p&gt;</content><category term="Technology"/><category term="AI"/><category term="AWS"/><category term="Red Hat"/><category term="Personal Projects"/><category term="ramalama"/><category term="Infrastructure"/></entry></feed>