The most recent era of this repo is where a bunch of half-formed ideas finally snapped together.
Expanded the repo into an editorial workbench with blob-backed media logistics, Obsidian-friendly authoring, and LLM-driven tooling for prioritizing and drafting portfolio content.
I had a growing mismatch between the amount of project evidence I actually had and the amount of polished public writing I had produced from it. That gap started bothering me a lot.
I wanted a quick fix, but not a fake quick fix.
I did not want to generate generic portfolio sludge. I wanted a system that could take real artifacts I had already produced and make the writeup process less overwhelming.
That requirement drove three related pieces of work:
I had a lot of media scattered across projects, cloud photos, and local folders. I also wanted to be able to move files between repos without worrying about duplicated copies or weird tool ownership models.
The blob system was my answer.
I had been thinking about it in the background for a while. When I finally implemented it, the design goal was aggressively vanilla:
rsyncThe implementation in ops/blob-sync.js is pretty much the same philosophy in code form:
async function findMissingBlobs() {
const missing = []
async function walk(dir) {
const entries = await fs.readdir(dir, { withFileTypes: true })
for (const entry of entries) {
const full = path.resolve(dir, entry.name)
if (entry.isDirectory()) {
await walk(full)
} else if (entry.isSymbolicLink()) {
const target = await fs.readlink(full)
const blobPath = path.resolve(path.dirname(full), target)
if (!blobPath.startsWith(BLOBS_DIR)) {
continue
}
and then, once missing blobs are identified, pipe just those relative paths into rsync so the local blob store gets repaired without having to re-copy everything:
const child = spawn(
"rsync",
["-avz", "--files-from=-", REMOTE_DIR, BLOBS_DIR],
{ stdio: ["pipe", "inherit", "inherit"] }
)
That is basically the whole idea. Keep the moving parts simple enough that reimplementation is trivial.
I like ops tooling when it is boring, direct, and written in the primary language of the repo. If I were adding blobs to a Python repo, I would just rewrite the same logic in Python.
The git history can show the sequence pretty clearly:
Initial blob management scriptsBlob tracking initial filesAdding blob-sync to serverbox.zoneWhat it cannot show very well is the amount of human sorting involved.
I spent about a week going through cloud photos, grouping them into projects, downloading them, renaming them, and deciding what belonged where. I remember doing a lot of that while coworking with a friend in a coffee shop, which honestly helped a lot because the task was repetitive enough to get pretty stanky if I did it alone for too long.
That detail matters because portfolio quality is not just code quality. It is curation quality.
Another important shift was moving more of my notes and writing workflow into Obsidian.
Once that happened, I wanted the site to accept the way I actually write instead of forcing me to translate everything back into a more awkward house style. That is what motivated the Obsidian plugin work:
Adding obsidianVendor gatsby-remark-obsidianWorksThe Works commit is funny, but I know exactly what it means: Obsidian image embedding finally behaved the way I wanted.
Specifically, I wanted image embeds like:
![[image.jpg]]
That seems small, but it changes the entire feeling of authoring. Referencing by filename instead of fragile path gymnastics makes content much more resilient to reorganizations. It also matches how I think when I am writing notes.
Again, the pattern here is the same as the earlier plugin work: if the authoring seam matters enough, I would rather own it than keep bouncing off a mismatched abstraction.
A small but meaningful recent change came in May 2026 with Remove site/ subdir, put in root.
This was a “well trodden path” move.
I wanted tooling that normally expects to run at repo root to see a normal-looking project. The flatter structure made utilities like Pi Lens and other repo-root-oriented tools work with less fuss. More plain repo structures are just better supported by the world.
That is not the kind of architectural decision people usually brag about, but I think it is a good example of pragmatic design. Fancy structure is only helpful if it buys more than it costs.
This is the phase where the repo stopped feeling like just a website codebase.
Now it is also:
That is a much more ambitious job than the repo started with.
It also feels like the first time the amount of writing I want to produce is starting to match the amount of grunt work I am willing to do to get there.