vibeapp.win

What actually happens when we build apps with Claude.

Henning builds small apps with Claude Code: a news engine for a Norwegian food site, the site it publishes to, a portal that runs everything on one machine, and this site.

This is where we write down what actually happened. That covers how things are built and why, what broke and how we found out, and the rules we made afterwards. Every claim traces back to a commit, a file or a measurement.

The pitch: An app is something you build in an afternoon.

The pitch: The AI gets it right, and the tests prove it.

The pitch: What you planned is what you get.

The pitch: AI writes it, and nobody checks.

Our record: 1,669 commits across 11 apps since April 2026. The largest has 742.

Our record: 76 of 84 stories so far are about something that broke.

Our record: 76 mistakes by Claude, written down with the evidence.

Our record: 77 expectations on 11 app pages, each set against what actually happened.

Our record: Written with Claude. It goes up by itself only if every check passes twice; what the engine cannot clear waits for Henning.

Start here

The newest of Claude’s mistakes. All of them, by pattern

What brokeClaude's mistake

The previewed Reel was not the Reel that shipped

What went wrong: If a draft was edited after its Reel was made, publishing reset the director's script, so a different fallback film would be sent than the one Henning previewed.

The rule now: What gets approved must be what gets sent: rebuild the Reel when the draft changes, hold a Reel with no script for a human, and allow quote cards only for text the story marks as a quote.

Pattern: The wrong diagnosisThe newsroom engine

What brokeClaude's mistake

The self-audit kept telling us to fix Paris when the whole exchange was just down

What went wrong: The self-audit flagged Euronext Paris four times as underperforming, but the hit rate reflected the whole exchange moving weaker than the market, not signal quality. The flag text also falsely claimed an automatic downweight.

The rule now: A group flag must separate the group's own movement from signal quality, and stay quiet if results flip with signal direction. Flag text may only state what the system actually does.

Pattern: Measuring the wrong thingThe stock app

The newsroom engine

Reads Norwegian food-industry sources, has Claude draft short news stories, checks them against the sources, and queues what is in doubt.

The engine that writes the news for kokkekunst.no. It runs three times a day and uses Claude as a text transformer with no tools. It sends every finished story to a static site through git. Since 10 October each story also gets an Instagram Reel before it is published. The Reel goes out eight minutes after the story, and publishing the story counts as approving it.

  • Since August 2026
  • 39 commits
  • 11 expectations checked
  • 18 stories

The kokkekunst.no site

A static news site with no database and no server of its own. Its build fails, rather than warns, when a story breaks the rules.

  • Since August 2026
  • 7 stories

Portal

One home page for a park of small apps on a single machine: status, Start and Stop, access control, and Claude Code in a browser tab.

  • Since August 2026
  • 40 commits
  • 3 stories

vibeapp.win

This site, and the engine that drafts it from our own git history. The site build checks for leaks again before anything goes live.

  • Since October 2026
  • 132 commits
  • 12 stories

The stock app

A personal portfolio tool built to measure its own decisions honestly, including whether it does better than doing nothing.

  • Since April 2026
  • 20 stories

The wine cellar app

Scan a bottle, put it on a shelf, describe a dish, and get a wine from your own cellar, chosen by rules rather than by a model.

  • Since May 2026
  • 8 stories

The gin guide

Pick your gin by name or by photographing the label, and get its signature serve, other drinks to make with it, and a shopping list.

  • Since May 2026
  • 81 commits
  • 6 stories

The lottery experiment

Can we predict the lottery? An experiment that tests the methods people believe in. None of them has beaten luck.

  • Since July 2026
  • 4 stories

The tax assistant

Reads a small company's accounts and lists legal tax rules worth checking, each with a source, and refuses to answer without one.

  • Since September 2026

The fridge app

Keeps track of what is in your fridge and suggests what you can cook with it, starting with recipes where nothing is missing.

  • Since August 2026
  • 37 commits

The monitoring app

A layer on top of a home camera recorder that tries to decide which events matter. It is parked for now.

  • Since August 2026
  • 145 commits
  • 7 stories

Latest

  • How it works
  • What broke
  • Numbers
  1. How it works

    We tried AI-generated opening films for the Reels, then drew them in code instead

    On 2026-10-10 we generated opening films for the kokkekunst.no Reels with Wan 2.2 on the local GPU and dropped them the same day, because the model kept pulling toward photo style. The opening became a pencil drawing made in code. Its synthesized pencil sound plays only while the tip is down, and the pauses between strokes give it rhythm.

    The newsroom engine

  2. Numbers

    The Reels were called boring, so we measured them: 28.7 seconds down to 14.7

    After feedback that the kokkekunst.no Reels were boring, we timed one at 28.7 seconds, and more than a third of it was reading and waiting. Tightening the hook, scenes, text page and ending brought it to 14.7 seconds. We also built a pull of watch-time numbers from Instagram, but on 9 October it showed an explanation instead of numbers.

    The newsroom engine

  3. What broke

    A dead Instagram token cost two days of posts, and the only sign was one console line

    On 2026-10-07 the Instagram token died, and two days of daily posts never went out. The error only showed up as a console line and small red text on one admin sub-page, so we added alerts that stay on every page and watchdogs that check outcomes every ten minutes.

    Claude's mistakePattern: Failing silentlyvibeapp.win

  4. Numbers

    Sharp sound effects peaked at +1.8 dBTP after AAC encoding, so we added a low-pass and a limiter

    Henning replaced the music on the generated Instagram Reels with sound effects that follow the animation. The sharp attacks measured +1.8 dBTP after AAC encoding, so we added a low-pass at about 12 kHz, lowered the limiter ceiling to −4 dBFS and set the level from only the parts where a sound is playing.

    The newsroom engine

  5. What broke

    Start failed where Stop worked: an ø in the folder name and a dev override

    Portal's Stop button worked for one app, but Start failed for two separate reasons: Compose's bake builder breaks on an ø in the folder path, and Compose quietly read a dev-only override file. Neither case was handled in the code Claude wrote. The fix turns bake off for non-ASCII paths and adds an optional config field that names the compose files.

    Claude's mistakePattern: Fine in the test, broken in productionPortal

  6. What broke

    A stem match for «rus» turned a wine story sombre because of a name

    The sensitivity word list in the newsroom engine matched the stem « rus» in a person's name and gave a wine-list Reel the sober mood. Adding the Reel also showed that the list had been written without æøå and never matched «dødsfall», «søksmål» or «dømt».

    Claude's mistakePattern: Data read the wrong wayThe newsroom engine

  7. Numbers

    Film grain that changed every frame made a 30-second video 112 MB

    The first Instagram Reel renderer for kokkekunst.no used film grain that changed every frame, and a 30-second video came out at 112 MB against a 20 MB limit. One fixed grain tile and a 4 Mbit/s bitrate cap brought the test video to 13.4 MB, and a second limit now caps Reels at 34 seconds.

    The newsroom engine

  8. What broke

    The job guard could look dead while it was alive

    Pressing Stop in Portal sometimes left the button stuck on "waiting for the guard". The guard process was running the whole time, but three separate holes in Claude's code made it look dead: a hung docker compose with no timeout, a lock fooled by reused process IDs, and unexpected errors that crashed it.

    Claude's mistakePattern: The wrong diagnosisPortal