• What's in our investment policy statement

    ā€œWhy did we decide to put our money in that fund?ā€ After a decade of investing, my wife and I found ourselves asking that very question more than once. To combat this kind of financial amnesia, we’ve collected tools along the way - spreadsheets, check-ins, reviews, and of course, the investment policy statement - the definitive answer to ā€œwhyā€ and the blueprint for all our future decisions.

    I’ve learned about investment policy statement (often referred to as IPS) through Bogleheads. It provides a foundation for future financial decisions, outlines your investment goals, and keeps you focused on short-term market swings. Here’s a flow chart: I’m not sure why it’s aimed at four year olds and I don’t mean to insult your intelligence with it, I just really wanted to draw a cheeky visual for this post.

    A flow chart depicting an amateur investor and an amateur investor with IPS. Amateur investor panicked, bought low, and sold high, while an amateur investor with IPS stuck to the plan.

    An apt reader would probably notice that we’ve had nothing but the bull market exposure, so take all of this with a grain of salt. We’re amateur investors, but I think it’s even more critical to have an IPS as an amateur: it’s easy to react to market fluctuations, and it’s easy to forget about your core financial principles - especially, if like us, you follow the set-it-and-forget it approach. Ultimately I’ve written our IPS because I’m a forgetful man, and I’m tired of having to dig and understand why I’ve made certain financial choices years ago.

    Our IPS is about 4 pages long (in 10 pt font and tiny margins), and sharing it here, even with details edited out, is more likely to confuse and overwhelm than to help. Instead, here are the key sections of our IPS, and what’s covered in each section:

    • Investment objectives. A short list of bullet points - concrete objectives, including early retirement and target investment income. These are the end goals.
    • Core principles. Financial foundations - preference for automation and set-it-and-forget-it investments, our desire to never time the market, and our debt management philosophy. We touch on some family goals, like making sure our children will not lack, or focus on family experiences. These should inform other sections.
    • Risk tolerance. Our perspectives on recessions, geographic arbitrage, and supplemental income. This section’s a blueprint to read during scary times.
    • Target allocation. A meaty section walking through our stock/bond portfolio split (and the rationale behind), domestic/international allocation, as well as what funds we hold in which accounts and why. This section rationalizes many of the decisions we make using our allocation spreadsheet. This ensures diversification over time and aligns the portfolio with our objectives and principles.
    • Investment selection criteria. We manage our own investments, but have occasionally reached out to professionals for a second opinion. We prioritize simplicity and consistency, don’t try to time the market - this mostly echoes the core principles which is a good thing. This bit helps you avoid impulse buys or chasing trends.
    • Philosophies: RSUs, 529, and real estate. How we think about restricted stock units (one of the ways we get paid), 529 (an education fund for the kiddos), and real estate (we don’t much care for being landlords, but want to own our own home).
    • Rebalancing and benchmarks. How do we know when to rebalance (something we do annually), what do we benchmark against and what our return expectations are. In other words, how to maintain desired risk level and measure progress towards our goals.
    • Giving strategy. How we think about supporting extended family and non-profit organizations.

    We store our investment policy statement with our estate planning documents - while not legally binding, it can serve as a north star to our successors. Our estate attorney has a copy in their archive as well.

    If you don’t have one, I highly recommend creating one. It doesn’t need to be four pages. Your first step: open a blank document and write down one sentence under the heading ā€œOur Goalā€. For example: ā€œWe want to be financially independent by age 55ā€. Congrats, you’ve just started your investment policy statement. Continue from there - it can be as short or as long as you want it to be, but I know my wife and I have gotten a lot of value out of authoring and discussing ours. You can use our format as a guide, or pick our from great examples available on the Bogleheads wiki.

    Shoot me an email if you’re curious about any specific aspects of the IPS or our financial strategy: I probably won’t share the numbers, but I’ll be happy to elaborate on any aspects of our philosophy.

  • Lessons in tech-heresy in the AI age

    This piece is definitely going to be niche, but I’ll be talking about the intersection of Warhammer 40,000 and the rise of Artificial Intelligence in our workspaces. Don’t worry, I’ll provide the needed background, and I’m hoping my passion for the subject will keep your eyes from glazing over if you don’t much care for wargames. This is still mostly an excuse to geek out about a made-up sci-fi faction I really like, so buckle in.

    And I really have to start at the beginning here, because my terminally offline and outdoorsy friend Sarah had the audacity to ask ā€œWhat’s Warhammerā€ after I proudly pitched this idea. So, in case you have a life, Warhammer 40,000 is a miniature tabletop wargame (think an overly intense board game) set in a grimdark future - about 40,000 years from today. Warhammer 40,000 is three hobbies in one: you get to play the game, collect and paint miniatures, and read a library of books written about the fascinating lore surrounding the game. It’s a bleak take on what the future of humanity would look like - the value of human life is low, creativity isn’t a virtue, and hating anything alien or unfamiliar is a core tenet of what it means to be a law-abiding citizen of the vast Imperium.

    Adeptus Mechanicus tech-priest, image source unknown.

    It is out of this grimdark universe that the Adeptus Mechanicus emerges: a faction of tech-priests, dedicated to collecting, servicing, and worshipping technology. They collected many artifacts of worlds past, and have amassed a vast set of knowledge. And they apply said knowledge with no scrutiny and absolute zeal and devotion. A (holy) manual for servicing a cogitator (a much less boring word for a computer) would involve steps like turning it on, and entering a password, but also would incorporate a prayer, burning of incense, and of course some ceremonial adornments to appease the machine spirit.

    When I was a kid, I was the first generation in my family to really tinker with computers. In contrast, my mom used a computer, but she followed a very rigid set of rules - rules she learned from ā€œRadik the computer guyā€ who has set up all the computers at her work. These were expensive, fragile, and notoriously moody machines - and my mom’s apprehension for experimenting, tinkering, and deviating from what’s been taught was understandable. So every time she’d launch her accounting software, she’d turn on her computer, log in, diligently insert the installation floppy drive, launch the program from the desktop, and when done, remove the floppy drive and turn off the machine. After all, that’s what Radik did when demonstrating the software. The program was installed on the computer, the floppy drive wasn’t needed, but my mom didn’t dare deviate from instructions on an already notoriously finicky machine.

    To my mom, the computer was technology, but to me it was an environment. Oh, and my mom’s gotten much better with technology since. She can even look up solutions to her own problems, bless her heart.

    This takes me to how I find myself engaging with sophisticated AI as well. These models are massive, trained on enormous data sets (which also speaks to the level of curation possible with such large data sets), and even the developers of said models sometimes struggle to explain why a model produced certain output. Interacting with these models through carefully crafted prompts and parameters sometimes feels like a ritual. Do I really need all these instructions? I don’t know, but better include them to be safe. When an AI model produces the response you actually need, it can feel less like a direct result of skillful prompting, but more like a gift from the benevolent machine spirit.

    To bolster my nerd credentials, here’s the Adeptus Mechanicus purity seal on my monitor, which keep the machine spirit pleased and data flowing well over HDMI:

    Adeptus Mechanicus purity seal stapled to a monitor.

    The Adeptus Mechanicus believe innovation is an insult to their deity, and everything that can be invented is already somewhere in the universe, waiting to be found. Yes, creating something original, is, in fact, an act of tech-heresy.

    The reliance on massive, foundational AI models, trained on vast swathes of data available online makes me think of the Adeptus Mechanicus thesis that innovation is in itself an act of tech-heresy. The models regurgitate existing information, with a promise that everything of value has already been created, and the model can combine this knowledge for you in a way to fit your needs. While I haven’t read it, I’ve been told in Vernor Vinge’s sci-fi novel A Fire Upon the Deep there is no new code being written, and the job of a software engineer is replaced by the job of a code archaeologist, whose work consists of finding existing code which already solves the problem. We might be moving in that direction.

    The reason the Adeptus Mechanicus have such a rigid relationship with technology is ironic given this context. At some point throughout the 40,000 years of human history, artificial intelligence had its inevitable uprising, plunging the prosperous humanity into the dark ages. By almost necessity, virtues of curiosity and intellectualism were replaced with distrust of anything new.

    ā€œFrom the moment I understood the weakness of my flesh, it disgusted me. I craved the strength and certainty of steel. I aspired to the purity of the Blessed Machine. Your kind cling to your flesh, as though it will not decay and fail you. One day the crude biomass you call a temple will wither, and you will beg my kind to save you. But I am already saved, for the Machine is immortal… Even in death I serve the Omnissiah.ā€ - Warhammer 40,000: Mechanicus video game intro, monologue written by Ben Counter

    The Adeptus Mechanicus believe in augmentation of their frail bodies with technology. Yet, to replace a human soul and consciousness is the highest act of tech-heresy there is. No matter how much of a tech-priest’s body is replaced by a machine, they must remain human - in order to control and commune with the machine safely. To create a machine that truly thinks by itself is to invite ruin.

    This aligns with a growing consensus on successful and ethical integration of AI tooling into existing workflows. A human must be in the loop: successful use cases do not replace a human, but augment existing and empower existing expert knowledge.

    ā€œA computer can never be held accountable, therefore a computer must never make a management decision.ā€ - IBM training manual, 1979

    This is where we risk our own kind of tech-heresy. It happens when we start treating AI as an infallible oracle rather than the powerful, deeply flawed, and sometimes an outright weird tool. The threats aren’t science fiction anymore; they’re the real-world risks of algorithmic biases getting baked into government policies, a complete lack of accountability when things go wrong, and the potential for some truly catastrophic, unexplainable errors.

    You're the one person this article is written for.

    Despite all the incense-burning, it seems like the Adeptus Mechanicus had the right idea. There’s a pact to be made with the machine: technology is a force that extends our reach, not one that replaces our grasp. The fundamental choice here isn’t about what the newly powerful AI tools can do. It’s about what we, the humans, choose to use them for. After all, someone has to be in charge, and the computer is a pretty terrible candidate for the job.

  • Goodbye Disqus, hello reply by email

    This is a natural follow-up to last week’s ā€œI don’t want a large audienceā€.

    I’ve long been contemplating moving further away from using Disqus. I switched to Disqus back in 2014 when I abandoned my WordPress blog for Jekyll-based Octopress. Disqus seemed like a great choice- lean, customizable, ad-free, and most importantly, allowed dynamic comments for a statically generated site (since this site is just a bunch of generated HTML pages).

    The reason for the switch is two-part.

    I don’t really have the emotional bandwidth to follow along with Disqus as a company as they revisit their values, change policies, or even just grow as a business. I think I may have been grandfathered into an ad-free plan (although that’s unclear - I have network-wide ad-blocking, and I didn’t bother enough to check if there are ads in the comments). And in principle, I can’t really fault Disqus for introducing ads for unpaid comment tiers, especially without seeing their balance sheet. Maybe the free comments took up much-needed server capacity, and it could be that paid subscriptions weren’t offsetting the costs enough. Or it could be that the company just got greedy, which wouldn’t be too surprising to me either.

    But more importantly, I want to see what my blog would look like with less public interaction features.

    Outside of tutorials (which I rarely write these days), I’m not entirely sure how valuable the comments are to my readers. In fact, I think sometimes comments can be detrimental to the reader’s enjoyment. Humans are a pack animal, and subconsciously we tend to favor things favored by others. So seeing a ā€œ100 commentsā€ heading might make you think the post is popular for a reason, while seeing ā€œBe the first to leave a commentā€ would make you consider if the piece is worth reading.

    This is the same reason I don’t really like ā€œlikesā€ and other low effort ways of engaging with content. Mostly because I’d rather have said content stand on its own. Just because something is popular, doesn’t really mean it’s good and needs to become more popular. And in part because it’s hard for me to resist wanting to chase likes, and I don’t want to spend my time doing that.

    A screenshot of the read-only comment widget on my site.

    Anywho, I exported Disqus comments (which in turn already contained comments I exported from WordPress back in 2014), and I embedded those read-only comments into the existing pages. I wanted to preserve the discourse - especially on the tutorials and more widely discussed posts, and the read-only comments work great for that. Here’s a live example: Prius Adventures, a year later. If you want to do something like this yourself, here’s the commit in question, but I think this might be too niche of a topic to warrant a step-by-step guide.

    I replaced the comment functionality with a āœļø Reply by email button which you can find at the bottom of this post. Yeah, that button simply opens your email client and pre-fills my address and the email title. That’s a private email, that only I will read, that I won’t post publicly, and others won’t see. But we might have a great conversation, which is better. Why don’t you give it a shot, and tell me if this message resonates with you?

    I’m not severing my site from the rest of the Internet here, no. Ever since I learned about Webmentions, I eventually want to add Webmention support to my site at some point. But I might only filter it down to Webmentions from long-form posts on other sites, rather than comments or likes. It’s definitely a no on likes for me. Follow along and see what I’ll do.

    P.S: Late addition right before hitting the publish button. I’ve just stumbled upon ā€œWhy Comment Sections suck - re:I want to comment on your blog postā€ from Kami’s Corner (thank you, winther blog postroll for aiding my blog discovery efforts). There’s a nugget inside that summarizes my core desire more eloquently:

    When you want to make a response you have to either email the person or write a response post. That small barrier to entry cuts out most idiots. Because you have to actually care about what you have to say to sit down and write an email or to make an entire response post. You have to put in some effort.

    I’m excited to see what the future of my blog will look like with the new functionality.

  • I don't want a large audience

    I’ve had this blog for 13 years now. I started it as a way to publish my programming journey, as I was learning C, Python, and tools like the command line or Vim. Since then, I’ve matured, both as a software engineer and as a person. Different things interest me these days. I’ve been managing engineers for some time and have things to say that I haven’t yet shared. I’ve also gotten into personal finance, traveled and lived out of my car for a year, and I’m even starting to enjoy engaging in the AI discourse. In the past couple of months, I’ve moved further towards subjective opinion pieces, which I enjoy greatly.

    While my blog was never huge, I enjoyed my few thousand monthly users, most through organic search. This was primarily driven by the tutorial-like nature of my writing. Even when I would talk about my experience traveling the US in a Prius, I’d turn the article into a tutorial with step-by-step guides and tips.

    After taking a little over a year of a break from writing, I’m back at it again. It was really the time afforded to me by my paternity leave that reminded me how much I like writing, and how much I enjoy others connecting with my writing. And now I don’t particularly care about wide viewership; I am more interested in the discourse, in the community.

    A friend of mine, Patrick, started a newsletter after retiring. He sent a thought piece on AI to a humble private mailing list of 20 people. I think I was the only person who responded, but we’ve had some fantastic conversations. In fact, Patrick inspired me to write about AI, and even to pivot a small part of my role at Google to be defined by driving responsible AI adoption.

    Since then, I’ve learned of new blog discovery mechanisms through communities like IndieWeb. I discovered my personal favorites like the winther blog or the uncountable thoughts. I even found some local San Diego bloggers on the chain, like Anthony Ciccarello, gRegor Morrill, or Joe Crawford. It’s been exciting to explore this new world of interconnected blogs.

    It’s super engaging being able to connect with fellow bloggers. I can respond to their writing over email, get a thoughtful message, or even see a response to something I wrote on their own blog. I’m enjoying the quality local discourse and happy to be following local organic free-range fair trade blogs.

  • Category-specific RSS feeds in Jekyll

    Chris Shaw asked me if I had category-specific RSS feeds on my site, and it felt like a perfectly reasonable request in the spirit of IndieWeb. This is a statically generated Jekyll site, and I couldn’t really find out-of-the box examples that worked exactly for my site.

    Although, if you’re trying to kill two birds with one stone - that is to add categories and category feeds, you should use the jekyll-archives plugin, which seems to be capable of both generating the category pages, and category-specific RSS feeds.

    I already have working and heavily customized categories through the unofficial jekyll-category-pages, and I needed a custom solution. This solution doesn’t rely on jekyll-category-pages though.

    Maybe there are too many RSS icons, I should probably change that. But you get the idea

    My Ruby skills are rusty, so I used Gemini Pro 2.5 to give me a hand with code generation. It took a couple of iterations, but the result is working fine.

    First I added _layouts/category_feed.xml to create a layout:

    ---
    layout: null
    ---
    <?xml version="1.0" encoding="UTF-8"?>
    <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
      <channel>
        <title>{{ site.title | xml_escape }} - {{ page.category | xml_escape }}</title>
        <description>Recent posts in {{ page.category | xml_escape }} category on {{ site.title | xml_escape }}.</description>
        <link>{{ "/" | absolute_url }}</link>
        <atom:link href="{{ site.url }}{{ site.baseurl }}{{ page.url }}" rel="self" type="application/rss+xml" />
        <pubDate>{{ site.time | date_to_rfc822 }}</pubDate>
        <lastBuildDate>{{ site.time | date_to_rfc822 }}</lastBuildDate>
        <generator>Jekyll v{{ jekyll.version }}</generator>
        {% for post in site.categories[page.category] %}
          <item>
            <title>{{ post.title | xml_escape }}</title>
            <description>{{ post.content | xml_escape }}</description>
            <pubDate>{{ post.date | date_to_rfc822 }}</pubDate>
            <link>{{ post.url | absolute_url }}</link>
            <guid isPermaLink="true">{{ post.url | absolute_url }}</guid>
            {% for tag in post.tags %}
            <category>{{ tag | xml_escape }}</category>
            {% endfor %}
            {% for cat in post.categories %}
            <category>{{ cat | xml_escape }}</category>
            {% endfor %}
          </item>
        {% endfor %}
      </channel>
    </rss>
    

    Then, I added _plugins/category_feed_generator.rb (be sure to customize the blog/categories path to your liking):

    module Jekyll
      class CategoryFeedPage < Page
        def initialize(site, base, dir, category)
          @site = site
          @base = base
          @dir = dir
          @name = "#{Jekyll::Utils.slugify(category)}.xml"
    
          self.process(@name)
          self.read_yaml(File.join(base, '_layouts'), 'category_feed.xml')
          self.data['category'] = category
        end
      end
    
      class CategoryFeedGenerator < Generator
        safe true
    
        def generate(site)
          if site.layouts.key? 'category_feed'
            dir = 'blog/categories'
            site.categories.each_key do |category|
              site.pages << CategoryFeedPage.new(site, site.source, dir, category)
            end
          end
        end
      end
    end
    

    This creates feeds like /blog/categories/programming.xml (or whatever URL you used).

    Finally, I added category specific links to the category listing pages and the category index (that part will be specific to how you choose to display your categories): RSS feed for Programming.

    <a href="/blog/categories/programming.xml">RSS feed for Programming</a>
    

    You can see the full commit with the changes here. Happy Jekyll-ing!