Work
Four things I built, with the true state and the hard part of each one.
I picked four instead of listing everything I have built. The reason is in the first chapter of my guide on product validation: a folder with forty started projects is not proof of creativity, it is a record of how many times the hard part got postponed. These four can be opened and checked. For each one I wrote down what the real problem was, which usually says more about the person building than the list of technologies does.
Compartmentalizer
In productionMy own deployment platform, in Python, on a VPS: it takes a commit, builds the Docker image, checks the health of the new version, and only then puts it in front of traffic. Every application runs isolated, with its own database, network and resource limits, and backups leave encrypted for off-site storage every night. It is what keeps this site and the rest of the studio's applications up.
There is no link to open, because it is not a website. The proof is this page: it is being served by it right now, as are the others on this list.
The hard part
Swapping the running version of an application without taking it down. The new one only gets traffic after it answers a health check, with the old one still up, and the system rolls back on its own if it does not answer. Applications that hold private keys are the deliberate exception: those stop first, because two instances holding the same key is a worse problem than a second of downtime.
Moto Spotters
LiveA community platform for motorcyclists in Portugal: profile and garage, groups, rides with a passport of stamps verified by the organiser, motorcycle club management (members, dues, documents), peer-to-peer bike sales with private messaging, and a directory of workshops and shops with quote requests. Next.js and PostgreSQL, installable as an app, with LLM content moderation.
The hard part
The moderation. What users write goes through an LLM before it becomes visible, across more than 25 content types, each with its own criteria. Wiring up the model was the easy part. The hard part was deciding what to do when it hesitates: block too much and you kill the community, block too little and you let through what cannot be let through, and the answer is not the same for a photograph as it is for a private message.
What is not done yet
The moderation runs in shadow mode: the model scores every piece of content and logs the decision it would have taken, but it does not block anything yet. It stays that way until false positives are calibrated against real data, and only then starts blocking.
DoutorWeb
LiveA web design agency for small businesses, with a dozen free tools you can use right away, no sign-up: quote generator, digital business card, digital menu, wifi QR code, image compressor, SEO checker. They serve whoever needs them today, and they show anyone considering hiring me how I work.
The hard part
Keeping the site fast while adding tools to it. Every new tool is one more page that has to open quickly on a phone with a weak connection, which is exactly where this service's customers are. Having a fast site on launch day is easy; still having one six tools later is not.
Smart account wallet on CKB
Testnet, private repositoryA smart account wallet on the Nervos CKB network where losing the device does not lose the funds. Spending requires the biometric confirmation of the phone itself (a passkey), verified by the on-chain contract and not by a server of mine: the key never leaves the device and the page stores nothing. Recovering access requires a minimum number of guardians chosen by the owner to agree, with a waiting period during which the owner can veto. Custom contract, in Rust.
See the transaction on Pudge ↗
The hard part
Getting a hardware passkey to authorise a transaction with no intermediary at all. The challenge the device signs has to be exactly the digest of the transaction, except that digest depends on the size of the signature, and the size is only known after the device signs. It is circular, and that is where this usually breaks. The fix was to pin the signature field to a constant size, padded at the end, so the digest is settled before anyone signs. Nobody notices this when it works.
What is not done yet
It is on testnet and it stays on testnet until there is an external audit done by someone else. The key that can upgrade the contract is still with me, and it is the last thing to close, after the audit. I write this here because the opposite would be exactly the mistake my validation guide spends twelve chapters trying to avoid.