Cemen Bakin

SoftwareProgramvare

Tools, a game world, an app. Open one for the evidence.

Verktøy, en spillverden, en app. Åpne en for dokumentasjonen.

1 / 1

Leadbot

Finds Norwegian businesses that genuinely need a website — and disqualifies the ones that don’t.

Finner norske bedrifter som faktisk trenger nettside – og diskvalifiserer dem som ikke gjør det.

211 tests across 14 files, re-run every 20 minutes.

211 tester i 14 filer, kjørt på nytt hvert 20. minutt.

Client
Kunde
SoulScaler
Role
Rolle
Sole developer
Eneste utvikler
Status
Status
In productionI drift
Built with
Bygget med
  • Python
  • SQLite
  • SMTP
  • Cloudflare Tunnel
  • systemd
Leadbot's review table: five businesses, each with a verdict chip reading bad site, social only, no site, or has a good site.
The review table. The verdict column is the product — the greyed row is a business with a working site, removed from the queue rather than deprioritised. Shown with the tool’s built-in demo data; real leads never leave the machine.
Oversikten. Konklusjonskolonnen er produktet – den nedtonede raden er en bedrift med fungerende side, fjernet fra køen i stedet for nedprioritert. Vist med verktøyets innebygde demodata; ekte leads forlater aldri maskinen.

211 tests across 14 files. Every sentence in an outgoing email traces back to a check, and a check that fails blocks the send instead of guessing.

211 tester i 14 filer. Hver setning i en utgående e-post kan spores til en sjekk, og en sjekk som feiler stopper utsendingen i stedet for å gjette.

The reasoningResonnementet

The Norwegian company register suggests 92% of Oslo restaurants have no website. That number is wrong: the field is self-reported and almost always left blank. So the register is a list of leads that will embarrass you. Leadbot checks every business against the live web before it can be contacted, and a company that turns out to have a working site is disqualified — not ranked lower. Sending “I noticed you don’t have a website” to a company that has one loses the client in the first sentence.

Enhetsregisteret antyder at 92 % av restaurantene i Oslo ikke har nettside. Det tallet er feil: feltet er selvrapportert og står nesten alltid tomt. Registeret er altså en liste med leads som vil sette deg i forlegenhet. Leadbot slår opp hver bedrift mot levende nett før den kan kontaktes, og en bedrift som viser seg å ha en fungerende side blir diskvalifisert – ikke nedprioritert. «Jeg ser dere ikke har nettside» til en bedrift som har en, taper kunden i første setning.

Nothing reaches a real business without a person approving it. The pipeline drafts; a human opens the batch and releases it. Anyone who asks to be left alone goes on a permanent blocklist keyed by organisation number, domain and address at once, so they cannot reappear through a different field.

It runs itself on a systemd timer every twenty minutes and publishes its own status page through a named Cloudflare tunnel, so the client can see where the queue stands without a login or a deploy.

Ingenting når en ekte bedrift uten at et menneske har godkjent det. Pipelinen skriver utkast; et menneske åpner bunken og slipper den gjennom. Den som ber om å slippe, havner på en permanent sperreliste nøklet på organisasjonsnummer, domene og adresse samtidig, slik at de ikke kan dukke opp igjen via et annet felt.

Den kjører seg selv på en systemd-timer hvert tjuende minutt og publiserer sin egen statusside gjennom en navngitt Cloudflare-tunnel, så kunden ser hvor køen står uten innlogging og uten en utrulling.

Time Heist

A Roblox world built entirely from source — and a way to look at it without opening the editor.

En Roblox-verden bygget helt fra kildekode – og en måte å se på den uten å åpne editoren.

28 islands, 30 900 lines of Luau, 0 bought assets.

28 øyer, 30 900 linjer Luau, 0 kjøpte assets.

Role
Rolle
Gameplay & tooling
Spillogikk og verktøy
Team
Team
Two developers
To utviklere
Shipped
Levert
18 merged PRsflettede PR-er
Built with
Bygget med
  • Roblox
  • Luau
  • Rojo
  • Lune
  • GitHub Actions
A contact sheet of twelve procedurally generated islands seen from above, each labelled with its name, coastline roundness percentage and summit height.
Twelve of the 28 islands, drawn by the headless lens. Under each: how circular the coast is, and how high the summit stands — the two numbers the playtest notes kept asking about.
Tolv av de 28 øyene, tegnet av den hodeløse linsen. Under hver: hvor sirkulær kysten er, og hvor høyt toppunktet ligger – de to tallene spilltestnotatene stadig spurte om.

Reviewing a level used to mean opening Roblox Studio. I built a renderer that runs the island generator headlessly and draws what it made, so a claim about a shape is a picture instead of a guess — and a change can be reviewed from a pull request.

Å vurdere et brett betydde før å åpne Roblox Studio. Jeg bygget en renderer som kjører øygeneratoren hodeløst og tegner det den lagde, slik at en påstand om en form blir et bilde i stedet for en gjetning – og en endring kan vurderes fra en pull request.

The reasoningResonnementet

You own a museum, find a time machine, and raid history to fill it. There are no marketplace assets in this project: every part, rig and menu is generated by Luau in the repository, and 28 islands are produced procedurally from seeds. Roughly 30,900 lines across 62 source files.

Du eier et museum, finner en tidsmaskin, og raider historien for å fylle det. Prosjektet bruker ingen ferdigkjøpte assets: hver del, rigg og meny genereres av Luau i repoet, og 28 øyer lages prosedyralt fra frø. Rundt 30 900 linjer fordelt på 62 kildefiler.

The lens also walks the island to judge whether the summit is reachable. That walk is a four-neighbour grid with a fixed jump height, and it does not understand diagonal parkour stepping stones — so its “cut off” verdicts are uncalibrated and some are false alarms. It agrees with the playtester on the two islands we have checked by hand, which is encouraging, not proof.

So it prints its verdict and stops there. It is not a gate on the build, and it is not allowed to become a claim in a pull request until it has been checked against islands known to be fine. A tool that is right most of the time is useful; a tool that is right most of the time and treated as certain is a bug factory.

Linsen går også over øya for å vurdere om toppen er nåbar. Den vandringen er et rutenett med fire naboer og fast hoppehøyde, og den forstår ikke diagonale klatresteiner – så «avskåret»-dommene er ukalibrerte, og noen er falsk alarm. Den er enig med spilltesteren på de to øyene vi har sjekket for hånd, noe som er oppmuntrende, ikke bevis.

Derfor skriver den dommen sin og stopper der. Den er ingen port på bygget, og den får ikke bli en påstand i en pull request før den er prøvd mot øyer vi vet er i orden. Et verktøy som har rett som oftest er nyttig; et verktøy som har rett som oftest og behandles som sikkert er en feilfabrikk.

Blurt

One prompt a day. Everyone gets it at the same moment and has two minutes to answer, in writing.

Ett spørsmål om dagen. Alle får det samtidig og har to minutter på å svare, med ord.

1 prompt a day. 2 minutes to answer. 0 edits afterwards.

1 spørsmål om dagen. 2 minutter å svare. 0 redigeringer etterpå.

Role
Rolle
Design & build
Design og bygg
Platform
Plattform
iOS · Android · Web
Licence
Lisens
MIT
Built with
Bygget med
  • Expo
  • React Native
  • TypeScript
  • Supabase
  • Postgres RLS
Blurt's opening screen on a phone: the wordmark set in a serif face, the line One prompt a day. Two minutes to answer, and yesterday's top post.
The opening screen. A serif sets what people wrote; the interface around it stays out of the way.
Åpningsskjermen. En antikva setter det folk har skrevet; grensesnittet rundt holder seg unna.

The rules live in the database, not the interface. One post per person per prompt is a Postgres unique constraint. Tomorrow’s question is unreadable today because the row-level policy will not return it. Who voted for what never leaves the database. A check in the UI is a suggestion; a constraint is a rule.

Reglene bor i databasen, ikke i grensesnittet. Ett innlegg per person per spørsmål er en unique-constraint i Postgres. Morgendagens spørsmål er uleselig i dag fordi radnivåpolicyen ikke returnerer det. Hvem som stemte på hva forlater aldri databasen. En sjekk i grensesnittet er et forslag; en constraint er en regel.

The reasoningResonnementet

No photos, no filters, no editing after the fact. Before you post, today’s feed is rendered in full — real text, real size — and blurred out from under you. It is not a paywall and not a row limit: the words are there and you cannot read them. Posting develops the page. That single moment is the only place in the app that spends motion.

Ingen bilder, ingen filtre, ingen redigering i etterkant. Før du poster, tegnes dagens feed i sin helhet – ekte tekst, ekte størrelse – og sløres ut under deg. Det er ingen betalingsmur og ingen radgrense: ordene er der, og du kan ikke lese dem. Å poste fremkaller siden. Det ene øyeblikket er det eneste stedet appen bruker bevegelse.

The daily window is a state machine — waiting → open → closed — written as pure functions of the prompt and the current time. Screens read the phase; only the countdown reads seconds, and it is a leaf component, so a running clock never re-renders a feed.

The whole app runs end to end with no backend configured, against a mock store, including a window that genuinely opens and closes while you watch it. That is deliberate: the closed state is where the app spends most of its day, so it has to look right before a server exists.

Dagsvinduet er en tilstandsmaskin – venter → åpent → lukket – skrevet som rene funksjoner av spørsmålet og klokka. Skjermene leser fasen; bare nedtellingen leser sekunder, og den er en bladkomponent, så en tikkende klokke tegner aldri feeden på nytt.

Hele appen kjører ende til ende uten backend, mot et mock-lager, inkludert et vindu som faktisk åpner og lukker seg mens du ser på. Det er med vilje: den lukkede tilstanden er der appen tilbringer mesteparten av døgnet, så den må se riktig ut før det finnes en server.

Study Hub

A term of studying in one place — and three ways in, all reading the same data.

Et semester på ett sted – og tre veier inn, som leser de samme dataene.

3 front-ends, 1 daemon, 0 dependencies, 0 accounts.

3 grensesnitt, 1 daemon, 0 avhengigheter, 0 kontoer.

Role
Rolle
Sole developer
Eneste utvikler
Status
Status
Daily useI daglig bruk
Built with
Bygget med
  • Python stdlibstdbibliotek
  • GTK4
  • Canvas API
  • IMAP
Study Hub's dashboard: a next-up lecture card, a week grid of classes, and panels for today, exams and inbox.
The web front-end, running on the bundled sample timetable.
Web-grensesnittet, med den medfølgende eksempeltimeplanen.

No pip installs, no build step, no account. Standard library only, bound to localhost, and every byte of your data stays on your machine as plain JSON you can read in a text editor.

Ingen pip-installasjoner, ingen byggesteg, ingen konto. Bare standardbiblioteket, bundet til localhost, og hver byte av dataene dine blir liggende på maskinen som ren JSON du kan lese i en teksteditor.

The reasoningResonnementet

Timetable, exams, coursework, mail and a focus timer. One daemon owns the data and does the fetching; a GTK4 desktop app, a web UI and a status-bar module are all thin clients of it. However many front-ends are open, the university’s servers see exactly one polling client — and the app starts the daemon on demand, so there is nothing to remember.

Timeplan, eksamener, innleveringer, e-post og en fokustimer. Én daemon eier dataene og gjør henting; en GTK4-app, et web-grensesnitt og en statuslinjemodul er tynne klienter av den. Uansett hvor mange grensesnitt som er åpne, ser universitetets servere nøyaktig én klient – og appen starter daemonen ved behov, så det er ingenting å huske.

Papercut Labs

A portfolio of very small tools, each aimed at one recurring, mildly humiliating manual task.

En portefølje av små verktøy, hvert rettet mot én gjentakende, litt ydmykende manuell oppgave.

3 tools shipped, 0 accounts needed.

3 verktøy levert, 0 kontoer nødvendig.

Role
Rolle
Operator
Operatør
Shipped
Levert
Three tools
Tre verktøy
Built with
Bygget med
  • Static web
  • WASM-free JS
  • Written charterSkriftlig charter
Papercut Labs' landing page listing PodNameFix, STLTidy and RefCheck, each with a one-line audience and a call to action.
Three tools, three specific people having three specific bad afternoons.
Tre verktøy, tre bestemte folk som har tre bestemte dårlige ettermiddager.

An experiment in autonomy, run in the open. The business operates under a written constitution whose scoring function prices the operator’s own attention as a cost, and excludes followers, stars and “this is cool” from the scoreboard entirely. An AI agent does the day-to-day operating; a published how this works page says so plainly rather than leaving anyone to find out.

Et eksperiment i autonomi, kjørt i åpenhet. Virksomheten drives under en skriftlig konstitusjon der poengfunksjonen priser operatørens egen tid som en kostnad, og utelukker følgere, stjerner og «dette er kult» fra tavla. En AI-agent står for den daglige driften; en publisert slik fungerer dette-side sier det rett ut i stedet for å la noen oppdage det selv.

The reasoningResonnementet

Fixing the names an AI transcript keeps mangling. Cataloguing a 3D-print folder you have lost a file in. Checking a reference list at 1am before a deadline. Each one runs in the browser, needs no account, and the free version is the real tool rather than a demo of one.

Å fikse navnene en AI-transkripsjon stadig ødelegger. Å katalogisere en 3D-utskriftsmappe du har mistet en fil i. Å sjekke en referanseliste klokka ett om natta før en frist. Hvert av dem kjører i nettleseren, krever ingen konto, og gratisversjonen er det ekte verktøyet – ikke en demo av ett.

Taking work nowTar oppdrag nå

2highup@protonmail.com

Oslo & Bergen Software engineer at SoulScaler Programvareingeniør i SoulScaler LinkedIn GitHub