Case study
One engine, three deployments, two languages. Separated out of a site that kept serving its readers throughout.
A second instance is now a matter of configuration rather than a fork; the third took one evening. I worked with Claude.ai as a tool and say so plainly, because it is part of the answer to how one person delivers this much scope. This page describes how it is made and which decisions it rests on. It is written for people assessing engineering rather than an offer.
Paweł Gąsienica-Samek · backend developer, thirteen years in C# · kontakt@kolofon.dev
Where it stands
The version history is public, commit timestamps included — outages and reversals along with everything else. It is not a gallery of successes.
The engineering problem
A literary site grew large enough that its code stopped being the code of that one site. The task: extract an engine from it so that a second instance is a matter of configuration rather than a fork — and do it on a live site that has readers and cannot stop working.
The method came down to one question asked at every file: does this code know the name of the site it was written for. Four stages, a green build after each, no downtime.
Four things worth a look
Diagnosing a production outage: the white page
The server rendered complete HTML and the browser erased it. The symptom pointed the wrong way — suspicion first fell on that day's changes. The investigation was unblocked by a stack trace pointing inside the router: the object existed but lacked a field the framework expected on it.
Cause: two copies of the same package in one bundle, one creating the instance and the other reading from it. Root cause: a missing dependency lockfile. The fix took less time than the diagnosis.
A vulnerability found in review, not in a report
The key to the service route showing the event log was a constant in the engine's code. That meant every instance built on the engine shared one key — including instances belonging to other people. With one instance, an ugly constant. With several, a vulnerability requiring disclosure.
The key is now an instance secret with no default value. A default would have been the same mistake relocated.
Privacy settled at build time, not at render time
A setting switched off the engine signature in the footer, and it worked — the HTML contained not one occurrence of the name. A JavaScript file served from the same domain, however, held a constant with the name and address, because a condition read at runtime gives the bundler no way to drop a dead branch.
The decision moved to build time: the branch collapses to a literal and the text leaves the output. A scan of the whole built site finds nothing. The bug surfaced not from reading the code but from searching the artefact.
Two language versions with no central address map
Each language is a separate deployment with its own database. Entries carry a stable, language-neutral key, and a resolving route on the other side turns it into a local address. There is no map to maintain and no hub to ask for permission.
Working with AI — no pretence
This project was built with Claude.ai at the keyboard. I do not hide that and I do not regard it as a weakness — I regard it as a skill worth being able to demonstrate, because the gap between good and bad use of such a tool is enormous and it shows in the code.
The division is clear. The constraints, the architecture and the acceptance criteria are mine. So are the rulings: I rejected the proposal of a central directory for language versions, because it introduced the intermediary this engine was built against. Review, testing against the built artefact and deploying to production — mine. Responsibility for every bug on this page — mine as well, including the ones no test caught and my own phone did, on a Sunday evening.
The model accelerates writing and searching. It does not relieve anyone of the duty to know why a thing must work one way rather than another — and the twenty-two entries in the architecture series are the record of exactly that reasoning.
How I work
- Conventions written down, not memorised. Any mistake that returns a second time ends as a line in the documentation.
- Tests against the built artefact, not the development server. The gap between them is exactly where the most expensive bugs live.
- Drift detection before synchronising. A tool that overwrites somebody else's work without warning is worse than no tool.
- Platform constraints treated as a reviewer. A good deal here is done well because doing it badly simply would not have worked.
- Costs named out loud. Every decision in the architecture series states the price it is paid for.
Contact
I am looking for remote work as a developer. Thirteen years of backend in C#, and this project is the evidence that I take responsibility for the whole of a thing — from an architectural decision to a deployment and an outage at midnight.
Kolofon