Automation Should Be Like Iron Man, Not Ultron
Another way I’ve heard this put is “build mech suits, not robots.”
Iron Man’s exoskeleton takes the abilities that Tony Stark has and accentuates them. Tony is a smart, strong guy. He
can calculate power and trajectory on his own. However, by having his exoskeleton do this for him, he can focus on
other things. Of course, if he disagrees or wants to do something the program wasn’t coded to do, he can override the
trajectory.
Ultron, on the other hand, was intended to be fully autonomous. It did everything and was, basically, so complex that
when it had to be debugged the only choice was (spoiler alert!) to destroy it.
[... more]
Jun 5, 2025, 7:40 AM
I wanted to do excerpts to give the main blog page more of a “feed” than a “post list” feeling. Surprisingly there
wasn’t a straightforward / built-in way to do it in astro. The markdown => HTML conversion seems to happen as part of
loading a post collection, and any downstream methods like render()
just reuses that HTML.
When I looked around there were two bits of prior art:
- The top google result renders the post
body
with an external library and then truncates the result. I didn’t love this because it seemed error-prone,
e.g. it’s easy to truncate through the middle of a codeblock. Using
[... more]
Jun 4, 2025, 11:03 AM
finally setting this thing up
Jun 3, 2025, 12:00 AM
o/
May 15, 2025, 12:00 AM
The easiest way to dodge the The Creative World’s Bullshit Industrial Complex
in a hot field is to pay attention to case studies and field reports rather than breathless hype and over-generalized
speculation.
Field reports are first or second hand accounts of concrete use cases and things actually happened. e.g. “here’s what I
ran into when I built X,” “our team tried Y and here’s how it went,” etc.
Speculation may include a grain of reality (or not!) but is usually written by someone on the outside and followed up
with baseless conjecture. e.g. “X built Y in 3 days and this is why AI is coming for all our jobs,” “the new oculus is
so good soon we will all be living in the metaverse,” etc.
Jan 27, 2025, 12:00 AM
Real Intelligence:
Case of AI usage outside of the “usual” techno-sphere.
artificial intelligence (AI) was now handling some 40% of customer service inquiries and that that number had
increased from just 10% in a few short months.
Someone else, listening in on the conversation, asked if his in-house customer service team, seeing this trend, feared
for their jobs? But Kevin said no, that they loved the AI because it enabled them to spend more time solving the
customer service inquiries that required depth of touch
[... more]
Jan 20, 2025, 12:00 AM
Real learning (the kind that sticks) requires active effort and engagement with the material: building a toy project,
writing a critical essay, etc. Passive consumption (especially of short form media) should be treated as entertainment
more than learning.
The rule of thirds applies here. The valence when e.g. reading the average Twitter post tends to be pretty flat. There
are no “tough” sessions of scrolling the feed (or, conversely really “great” sessions), so how much growth is really
taking place?
[... more]
Jan 7, 2025, 12:00 AM
When you’re chasing a big goal, you’re supposed to feel good a third of the time, okay a third of the time, and crappy
a third of the time… and if the ratio is roughly in that range, then you’re doing fine.
Source: Bravey, Alexi Pappas
This probably applies to sustainable growth / “productive discomfort” in general. Corollaries: If you’re consistently
feeling good, say, >50% of the time, you’re not pushing hard enough to grow. If you’re feeling crappy >50% of the time,
you’re pushing too hard to be productive.
[... more]
Jan 7, 2025, 12:00 AM
on shortification of “learning”
Learning is not supposed to be fun. It doesn’t have to be actively not fun either, but the primary feeling should be
that of effort. It should look a lot less like that “10 minute full body” workout from your local digital media
creator and a lot more like a serious session at the gym. You want the mental equivalent of sweating.
If you are consuming content: are you trying to be entertained or are you trying to learn? And if you are creating
content: are you trying to entertain or are you trying to teach? You’ll go down a different path in each case.
Attempts to seek the stuff in between actually clamp to zero.
[... more]
Jan 2, 2025, 12:00 AM
A few weeks back I switched from Raindrop to Readwise for my reading, highlights, and related notes. The main reason for
switching was the Kindle integration, but part of my criteria is an API integration where I can automatically collect +
archive the data into my personal cloud. It ended up being a bit of a learning curve, so below are notes for anyone
who might be interested in doing the same:
The Readwise umbrella has two apps: Readwise and Reader. Readwise focuses on highlights + reviewing highlights, whereas
Reader is a web bookmarking + highlighting tool that’s more akin to Raindrop. The APIs are separate, with their own
docs + internal concepts:
[... more]
Dec 10, 2024, 12:00 AM
One of the annoying things about running the personal cloud is managing secrets (API keys, google creds, etc) for
the bits that run locally on my laptop.
So far I’ve just been shuffling these creds around local-only env files tied to a couple of start scripts. It’s kind of
a pain cause the files can’t be shared or committed to GitHub for obvious reasons so I have to walk on glass every time
I touch them. And lord help if I accidentally delete one of the files or get them mixed up somehow.
Last week I finally got tired of the nonsense and automated it via 1Pass. Apparently they have a nifty
[... more]
Dec 3, 2024, 12:00 AM
As part of building my personal cloud, I wanted to back up my browser history. This is useful for info mining and search
purposes, but also because Brave (or Chromium?) starts dropping data after 90 days. Who knew. The 90 day limit is
hard-coded, so data loss is unavoidable without an export.
So first, the location. On Macs this is ~/Library/Application Support/BraveSoftware/Brave-Browser/[Default || Profile N]/History/brave_history.sqlite
.
For chrome, the location is similar ~/Library/Application Support/BraveSoftware/Google/Chrome/[Default || Profile N]/History
[... more]
Nov 19, 2024, 12:00 AM
Over the years I’ve noticed people seem to have two fundamental orientations towards goals: aspiration-first and
reality-first.
Aspiration-first thinking starts with an external or motivational stance. For example: “I need to lose 20 lb before
summer to fit into my beach clothes / reach a certain BMI / etc” Or in business: “We need $1MM ARR this year because
that’s the benchmark for companies of our stage.” From there, achievement is throwing stuff against the wall till
something hits the right trajectory.
[... more]
Oct 15, 2024, 12:00 AM
Yesterday I was editing a photo on my phone when I got hit with a prompt: $3.99/mo for premium features! It really
feels like every software company and their mother wants to move to a subscription model these days. From a business
standpoint, I get it: recurring revenue brings warm fuzzy feelings and is easier to sell to financiers. But as a
customer it’s incredibly annoying when the pricing doesn’t match the value.
In this case, my thoughts ran through some usual tracks: Why should I pay a monthly fee for a photo editing app? They
don’t have any server or maintenance costs. All the work is done on my phone, and the photos live on my storage. And
it’s not like the software changes that often, only so many things you can do to a photo.
[... more]
Oct 8, 2024, 12:00 AM
Lately we’ve been thinking about fundraising at work. We’ve built a good product and a business with gathering momentum
and positive unit economics. Even without a raise we’re likely to be in the black in a reasonable amount of time –
knock on wood – or as Silicon Valley likes to say, default alive.
The knee-jerk response for early stage SV-style startups is “of course you should raise, you can grow faster!” But
another way to phrase “growth opportunity” is “upside risk,” and once you say “upside risk” the next natural thought is
“downside risk.”
[... more]
Aug 6, 2024, 12:00 AM
I first saw “zero-based budgeting” in some leisurely weekend reading on private equity firms (I know, party animal
comin’ through). The idea is to start each annual budgeting process “from zero” and justify all expenses from scratch
instead of anchoring on existing spend. “How much should we spend on X,” instead of “cut 5% off X this year”
This is a useful framework for other contexts:
- Every day you stay at a job is a decision to take that job, knowing what you know that day.
- Every day you hold an investment position is a decision to buy on that day’s price and fundamentals.
[... more]
May 24, 2024, 12:00 AM
How to Learn Better in the Digital Age
I see edutainment as preparation for learning: it’s a powerful explorative tool that can provide ideas and motivation
to learn. And yet, it’s also not learning itself, in the same way as buying running shoes is not running. Within this
framework, “mindless” browsing online can be transformed into scouting for learning opportunities.
The process takes a lot of time and effort, which means it’s not something I can afford to do with every piece of
content I find online. Most of the time I trash the links I find, upon further review. Sometimes they end up in my
learning wish list.
[... more]
Aug 21, 2023, 12:00 AM
As a part work on an old project, I used sqlite native fts for an MVP full text
search. The setup was interesting + ~mostly worked, so it deserves a quick walkthrough.
index + trigger setup
For the this walkthrough, let’s say I have a table bookmarks
with a title and a description field. First step is
setting up the index:
create virtual table
fts_bookmarks
using fts5(
title,
description,
content=bookmarks,
content_rowid=id
);
The content
option tells sqlite that this is an external content table
[... more]
Jan 30, 2023, 12:00 AM
Just finished reading Tomorrow, and Tomorrow, and Tomorrow
this past week and it’s the best fiction I’ve read in recent memory. Certainly the best realistic-ish fiction I’ve read
in years. Whether it’s the close demographic match (Asian immigrant, grew up with the internet, spent a lot of
childhood in virtual game worlds…), the fresh variation of style and framing devices, or quippy lines like “To return
to the city of one’s birth always felt like retreat,” this one just hit.
It’s not perfect book by any means. But chances are if you’re on this blog and still reading for whatever reason,
you’ll probably like it too. In the meantime guess I’m gonna read AJ Fikry just in time for the movie.
[... more]
Oct 9, 2022, 12:00 AM
For a while now I’ve felt like my zsh has been starting up more and more slowly. It’s one of those small annoyances that
builds up over time, especially if you pop a lot of shells via e.g. tmux and have to wait more than “One Mississippi” to
do anything. This week I finally got annoyed enough to do something about it.
before
Step one is to figure out exactly how slow and why. First I timed the init:
$ time zsh -i -c exit
0.71s user 0.58s system 52% cpu 2.479 total`
… Two and a half seconds?? Ouch.
[... more]
Aug 7, 2022, 12:00 AM
Roam Research is the darling of the latest wave of knowledge management / note-taking apps.
I’ve been using it for about two months now. tl;dr - Roam delivers on its promise of networked thought and the features
around bidirectional linking are extremely well-executed. However it does still have non-trivial downsides, for example
the mobile experience. So I’m not a card-carrying member of the #roamcult just yet but I will continue to use it, at
least over the short-to-mid term.
😄
- The affordances for bidirectional linking are super slick. A link can be created at any time by enclosing it in
double brackets, e.g.
[... more]
Dec 10, 2020, 12:00 AM
IO.inspect
is great for println debugging, and generally “does the right thing” with just about any input you throw at
it. Up until recently, I would use it in a way that looked something like this:
IO.puts("debugging pw validation (length)")
validated =
credential
|> cast(attrs, [:password])
|> validate_required([:password])
|> validate_length(:password, min: 15, max: 1000)
|> IO.inspect()
|> validate_complexity(:password)
|> hash_password()
… which is mostly fine, but the extra IO.puts
[... more]
Dec 5, 2020, 12:00 AM
One sentiment I see from people coming from dynamically typed languages (python, ruby) or even Java and C is a general
dismissiveness about static typing and compilers. At best, the sentiment is “Oh, well it makes sure my input is an Int,
or a Float, or a Bool… That’s cool I guess, but I can do that with TDD”. At worst, static typing is seen as
something to fight against — shackles that limit our creativity and bar us from what we really want to do and the
beautiful programs that we could write if only the type-checker got out of our way.
[... more]
May 20, 2016, 12:00 AM
% (Current File Name)
Another vim tip this week! This time, it’s about ‘%’, which expands to ‘current file name’. This is especially useful
in projects with java/scala style directory setups, where your source is approximately 1.5 million folders away from the
project root, but you kind of want to hang around project root for things like ant/sbt/etc to work. %
makes this
easier to work with files in the deeply nested folders while doing this.
Taking a contrived example, instead of doing something like this to
[... more]
Jan 24, 2015, 12:00 AM
Let’s talk about clojure for a bit. Or lisps in general, I guess. A lot of the “kinda joking except not really” quips
that commonly float around on the internet are about the parentheses, as in how there are so many of them. For example,
if you want to take a number x
and add one, multiply by two, then add 3, the code might naively look something like
this:
(+ (* (+ x 1) 2) 3)
Or perhaps like this:
(+ 3 (* 2 (+ 1 x)))
Look at the parens! Especially the consecutive 3 closing ones in the second variation. For a sufficiently long chain
of functions, it can get pretty unreadable—especially with multiple arguments and whatnot.
[... more]
Jan 24, 2015, 12:00 AM