Portfolio · System

The portfolio that keeps itself up to date

This site keeps itself up to date. Every morning it pulls new work and fresh numbers from Notion, checks that everything is right and puts it live. You're looking at it right now.

A portfolio starts aging the day you publish it. The numbers fall behind and the latest project is three months old, while the work just carries on. Updating is manual labour, and that is the first thing to slip.

So I built a portfolio that keeps itself up to date. The projects, the changelog, the growth chart and the numbers at the top of the site: none of them are typed into the page. Everything comes from two Notion databases I use daily anyway, and the site rebuilds and republishes itself every morning.


Outdated from day one

"I build AI systems" has become a cheap claim. Everyone puts it on their profile. The difference is whether you can click on it. I wanted a portfolio that is its own proof: a site that shows what's running, by running on it itself.

The practical problem was a classic. Every time something was finished, I had to open the site, edit HTML, upload files. You do that twice, and then never again. The records I did keep lived in Notion, where my tasks and projects already are. The solution was obvious: let the site grow out of those records, instead of maintaining a copy next to them.

Change the source, never the output.


One source and a fresh site every morning

Every project card, changelog line and toolkit tile on the homepage is a row in a Notion database, with a handful of fields that drive the behaviour: which section it lands in, whether it's published, and in what order. Adding a new project means creating a database row. I don't touch the HTML.

The core: three scripts
  • build_portfolio.py turns the content database into projects, changelog, toolkit and workflow on the site, in two languages at once.
  • build_timeline.py reads my task board and builds the growth chart from it, week by week.
  • update_hero.py refreshes the numbers at the top of the site, straight from the same source.

The scripts write their output between fixed markers in the page:

<!-- BUILD:portfolio:projects:start --> ... generated by build_portfolio.py ... <!-- BUILD:portfolio:projects:end -->

That rule enforces discipline: there is exactly one place where content lives, and it's not the website. Everything between the markers gets overwritten on the next build. The scripts are also predictable: a second run without database changes changes nothing, and a built-in count stops the build if items go missing along the way. A half-empty section never quietly goes live.

Since the latest rebuild, publishing isn't an action anymore. Every morning at a quarter past eight, the full pipeline runs by itself: refresh the content, and only if something actually changed does the site get republished. No change means no publication. The server also only accepts files on a fixed list, so an accidentally included internal file can never become public. It fails safely: a forgotten file simply doesn't appear, instead of the wrong file leaking.


Proof instead of claims

The strongest argument for this setup is that you're looking at it. The growth chart on the homepage shows hundreds of completed tasks, week by week, spread over fifteen skill domains. That data comes from the same task board I work with daily. The chart can't lie without my own records lying with it.

2Notion databases behind the homepage
08:15daily build and check
2languages from the same pipeline
0manual work per update

A fresh build every morning; publication only when something changed.

Meanwhile the site has grown from one page into a small ecosystem: project pages per system, an article series built from plain text files, and a bilingual variant built from the same databases. The pipeline grew along with it. It gained sources, and checks that stop the publication as soon as something is off, such as a dead link or an English page that still shows Dutch text.


Automatic is not the same as automatically good

The technology turned out to be the easy part. The hard part is editing. A system that publishes everything that's finished also publishes things that mean nothing to a visitor. So nothing goes live without a deliberate choice: every card has a status, and only what I set to "published" reaches the site. The AI helps write the copy, but a page only goes live after I've read it the way a visitor will see it.

And there's a second trap: tinkering with the system is more addictive than making content. An evening spent polishing the pipeline feels productive, but a visitor sees none of it. The rule I set myself: the system is done once it's boring, and the attention belongs to what it shows.


Three lessons from the rebuild

01
Half translated is worse than not translated

The first language toggle translated only the buttons, not the content. The result: an "English" site that was mostly Dutch. That system was removed entirely and only came back once the whole content pipeline was bilingual, with an English title and description field per card in the database.

02
Not every finished task is portfolio material

A version bump of a tool matters internally, but says nothing to a visitor. The filter for the changelog: something an outsider understands and that says something about what I can do. The rest stays in the records.

03
Verify the chain, not the assumption

The biggest bugs came from assumptions about how data flows: a file that turned out not to load, a structure that was flatter than expected. Since then I first prove what actually arrives at the receiving end, and only then build.


Make your own site self-updating

The setup isn't tied to my tools. All you need is one place where your work is already being tracked (a task list, a spreadsheet, a database) and the agreement that the site grows out of that. Let an AI sketch your own variant with the prompt below.

  1. Name your source. The place where your work already lives. That becomes the only place you still update.
  2. Name what the site shows. Projects, a changelog, numbers: pick what means something to a visitor.
  3. Let the AI make the plan. Starting small is fine: one section that refreshes itself is already a living portfolio.
Copy this prompt
I want my portfolio site to keep itself up to date, instead of me updating it by hand.

My situation:
- I currently track my work in: [for example: Notion, a spreadsheet, Trello]
- My site runs on: [for example: a static site, WordPress, no site yet]
- I want to show: [for example: projects, a changelog of finished work, numbers]

Interview me briefly first about what my records contain and how technical I am.

Then propose a setup with:
1. Which source becomes the single place of truth, and which fields it needs.
2. How the site gets built from that source, as simply as possible.
3. A safe publishing step, where I decide what becomes visible.
4. The first step I can take this weekend.

Be honest about what I'd better not automate.

Part of a bigger system

This portfolio is itself one of the systems it shows. The databases the site builds from are largely maintained by Kai, my AI assistant, and the knowledge behind the projects lives in my second brain.

Explore further

All projects this site shows are on the homepage, live from the source.

An example of what flows through this pipeline: the full build story of Wire Spine, an AI concept album.

See the living portfolio Meet Kai, my AI assistant