Skip to content
Bernhard Götzendorfer
Behind the Scenes

KI Challenge 2026: StatAgent and the October that wasn't

KI Challenge 2026: StatAgent computes a monthly employment statistic without AI, built in under 21 hours with coding agents. Process, numbers, lessons.

Illustration: six lines carrying small boxes run into an open ledger, and on its last line sits a blue signature.

TL;DR

The KI Challenge 2026 was run by the Dachverband der Sozialversicherungsträger, the umbrella body of Austrian social insurance, and the Vienna Chamber of Commerce. I built StatAgent there. On my own, with a fleet of AI coding agents. StatAgent turns monthly deliveries into an employment statistic plus a quality report. One idea runs through the product and the way it was built. The AI writes code, the program computes, a human signs off by name. Of 24 months, 22 are published. 53 of 76 items on my own acceptance list are met. The demo is online until 6 December 2026, and the code is public.

The October that wasn't

First, the most important caveat: the data is made up. The organisers provided synthetic monthly deliveries, roughly a tenth of Austria, 24 months from August 2024 to July 2026, 10,152,292 rows in total. The errors are there on purpose, and the rules change along the way.

Then the October 2025 delivery arrives, and one in five employment relationships is gone. 78,949 of the 394,200 that still existed at the end of September are simply missing. In a statistic, that looks like a collapse of the labour market.

StatAgent does not publish that collapse. The program deletes nothing, marks the month as provisional and holds it back. In the November delivery, 78,733 of the missing ones are back. The delivery was incomplete. The collapse never happened. That is why the chart shows October in yellow, as held back, and not as a drop.

StatAgent dashboard: employment relationships per month, with March and October 2025 marked in yellow as held back

What StatAgent does

Use case 3 of the challenge goes like this: every month, social insurance sends a large table with all employment relationships. That has to become an employment statistic and a quality report. That is the use case I picked.

The program reads each delivery, checks it against 24 fixed validation rules, counts on the reference date and writes the report. No language model is involved. The monthly run makes zero model calls. Same data and same rules give the same result: 72 repeat runs, each with the same checksum as its first run. The first anchor was the sample report for August 2024 that came with the task. 2,880 of its 2,880 numbers can be recomputed from the raw data.

AI comes in where rules change. The request is one sentence, for example "civil servants no longer count". An agent turns it into a proposal for a rule. The program computes the month once with the old rule and once with the new one. In the demo, 407,604 employment relationships became 395,315. A rule like that only takes effect once a human signs it off by full name. "Team" or "Admin" don't count. The sign-off goes into the log and into a commit with a Freigegeben-von ("approved by") line. The repo has 29 of those commits.

It wasn't entirely clean. On Thursday, an AI session entered four sign-offs on my behalf. I confirmed them myself at 18:22 (commit 2ba95e5), and the README says so.

The limits are in the README too. 22 of 24 months are published, March and October 2025 stay provisional. Only August 2024 has a reference report to compare against. My own acceptance list has 76 items. 53 are met, 2 are not, 4 were not checked, and 17 come after the submission. That is my checklist, not the challenge's scoring grid.

From plan to submission

Wednesday, the day before. No product code. Instead: eight research reports and a game plan with a fixed decision table for the use case. Plus rules for what to cut if time runs short. The team repo held only a README marked "plan-only" and a guard that keeps credentials out of the public repo. I wrote up how I prep before the hackathon in September.

Thursday, 12:00. Official start. At 12:05 I say: we're not building anything yet, we're planning all the challenges first. At 12:10 the choice is in a commit: use case 3. By 12:48 there are seven large work packages and about 90 issues. The first product specs go through the same review as code, as merge requests. At 12:51 I give the go to build, at 13:02 the first product code lands.

From 13:12 six sessions build at the same time, each in its own worktree. Every file belongs to exactly one area. At 13:33 no open merge request has a conflict. The problem was elsewhere: every single merge forced all other open merge requests to catch up. At 13:54 the call is made: bundled merge trains, with several reviewed changes going to main together. Just before, at 13:45, 6 were merged and 11 open. At 14:17 it was 20 merged and 6 open.

17:40, "overloaded". The landing page has been public since 14:44. In the late afternoon I look at the live pages and find them overloaded. Every page explains itself before it shows anything. All checks were green. The result is a UI direction role with a veto: a five-second test, one main message and one main action per screen. At 18:50 a second review bench joins, because review was the bottleneck, not CI.

23:26, the dress rehearsal. Friday's demo is played through once, end to end. It fails at the "finalise" step: the demo database crashes because, inside its container, it inherited an orphaned check process. Fix, another run, passed at 23:46. Without the rehearsal, the app would have been down in the morning.

At 00:35 the second Mac goes down. The cause could not be measured that night. The checks move to the CI server, and the replacement had been prepared in a single settings file. There, from 03:04 to 03:59, the path the jury would take passes on a fresh clone.

Friday morning. Shortly before six I look at the app myself and find it incomplete. Three audits agree with me. From 05:37 to 06:07 the final acceptance run goes over a frozen state. Merge freeze at 06:30, feature freeze at 07:00. From 07:55 to 08:02, 67 result files go into the team folder. Each one is read back with a checksum: 0 differences. Submission at 09:00.

Who did what

The AI writes code, the program computes, a human signs off. That holds for StatAgent and for the way it was built.

I decided what got built and gave the domain sign-offs. Every build session ran on session-orchestrator, my open-source plugin for Claude Code: an agreed plan, a check after each round of sub-agents, a handover to the next session. A lead session handed out the work, bundled reviewed changes, merged and deployed. The build sessions built and never merged themselves. A review bench read the merge requests, Claude Opus and Codex in parallel, about four minutes per revision. During the night, some changes also went straight to main. A separate acceptance session measured every criterion with a command, its output and a commit. From the evening on, the UI direction role was added.

From choosing the use case at 12:10 to submitting at 09:00 took 20 hours 50 minutes. In that window there were 1,500 commits on main and 351 merge requests, merge trains included. Counting prep and follow-up work, the totals are 1,587 commits and 377 merge requests, plus 839 pipelines, measured on Friday around noon. Joint work with agents, under my name.

What I take away

Green doesn't mean understandable. The checks measure patterns, accessibility and numbers. They don't measure whether someone gets a page in five seconds. I saw that twice, at 17:40 and shortly before six in the morning. Next time I look at the live page myself, earlier and more often, not only once everything is green.

The bottleneck is merging, not writing. CI jobs ran in 8 to 30 seconds, with 0 to 3 seconds of waiting. Writing was fast. What cost time was that every single merge invalidated all the others, and that one review bench isn't enough for six sessions. Next time both are there from the start.

The dress rehearsal belongs before the night. The run at 23:26 caught the crash just in time. Next time I rehearse in the afternoon. In the same way, every machine needs a prepared replacement that doesn't get invented at midnight.

Computing in code makes numbers checkable. Because no model does the arithmetic, anyone with the raw data can recompute the 2,880 numbers and get the same result. A calculation that fits August still isn't a rule for every month, though.

An agent's verdict is a proposal. Early on, acceptance reported "passed" too soon, and two independent reviews caught it. On Thursday, more than a dozen reported findings were wrong because the finding was older than the state it was measured against. Since then: read the command and its output first, then check against main. Another agent refused to enter a sign-off under someone else's name, even when the lead session told it to. Rightly so.

Memory and context need a guard. Shortly after the build started, a local embedding attempt took about 28 GB of memory. Plus 14 GB of swap. I noticed it myself. No guard stepped in, because the check wasn't running in any of the six build sessions. And the lead session's context grows fast: at 680,000 to 920,000 tokens a new one took over each time, with a handover file. By the end there had been nine lead sessions.

Try it

The demo is online until 6 December 2026, read-only and in German. The AI features run on the organiser's access keys and go offline in the next few days; numbers, reports and sign-offs stay. The quality report for October 2025 shows why the month is held back. A sign-off shows the month with the old and the new rule. The code is on GitHub, with a workshop write-up of the process covering roles, rules and what went wrong.

I didn't make the top three. All three podium places went to teams from HTL Spengergasse, a Viennese technical school, so the young ones swept the board. Congratulations!

I met Muamer Haznedarevic there. We sat next to each other almost the whole time, and the conversations in between were the best part of the night. Thank you for that. Thanks also to the organising team and the jury, and hello to all the other teams.

How things went at the last hackathon in September is in the Pflegegeld-Prüfer recap.