blog.gwrx.at

Today I aimed a normal household fan at the drying rack, purely out of "what could possibly go wrong", and the wash was dry in a fraction of the usual time.

My instinct was to say no AI would have come up with that. So I asked one. Of course it had: boundary layer, vapour pressure, temperature-humidity-airflow, the whole lecture, instantly, for free.

The answer had been sitting there the entire time. I never asked, because I didn't know there was a question.

That's the bit nobody has automated. The model will answer anything you put to it — it cannot be standing in your Waschküche at nine in the evening wondering what happens if you turn the fan around. Curiosity is still BYO.

Anyway. Since I had the lecture, here it is, short.

The whole thing is one equation

Water leaves your laundry at roughly

ṁ = A · k · (c_wet − c_air)

  • A — wet surface actually exposed to air
  • k — how fast moving air hauls vapour off that surface
  • c_wet − c_air — how much thirstier the room is than the fabric

Three knobs. Every dryer ever built, and every Kellerabteil full of dripping shirts, sits somewhere on that formula.

A is free and everybody wastes it. A towel overlapping itself has half the area it looks like it has. Spread everything, hang shirts open, turn pockets out. Cheapest term in the equation, costs nothing but rack discipline. Same reason a hard spin cycle beats everything else here — water thrown out mechanically never has to evaporate at all.

k is the fan. Wet fabric wraps itself in a thin skin of saturated air and then suffocates in it. The fan strips that skin off. But the payoff is sublinear, and that's the part that surprised me: in the textbook flat-plate case k grows with something like the square root of air speed, creeping toward U^0.8 once the flow turns turbulent. Take those as illustration, not as a measurement of your cellar — the point is only that doubling the wind does not double the drying. So: low or medium, aimed across the rack rather than blasting one unlucky towel. Evaporation is fastest where the air first meets the fabric, which makes rearranging things halfway through worth more than another 30 watts.

c_wet − c_air is the ceiling, and the term everyone forgets. Warm air holds more water, so a warm room drinks harder. But nothing described so far removes a single gram of water from your flat — the fan only relocates it out of your T-shirt and into the room. When c_air catches up with c_wet, the bracket goes to zero and your expensive wind is just noise. Opening a window helps only when the air outside is genuinely drier than the air inside; on a raw, wet November evening it isn't, and you've traded drying for heating.

And the room does not start empty. The Energy Saving Trust reckons a household can put up to 100 litres of moisture a week into its own air just by cooking, showering and breathing — and if that moisture isn't removed by ventilation, it settles on surfaces or stays in the air. A wet wash is more of the same, on top. That's the actual risk, and it isn't the fan's fault: it's water with nowhere to go, finding the coldest wall in the flat. Which is why the fan needs a partner that takes water out — extraction to the outside, or a dehumidifier.

So: spin it hard, spread it wide, a cheap fan across it on low, and give the water somewhere to go.

A tumble dryer does those same four things in a box. Tumbles the load to expose surface, blows air over it, heats the air to widen the gap, and either vents the vapour or condenses it into a tank. Nothing magic — just all four knobs turned at once, which is exactly the part I got wrong by only turning one.

I burned through a weekly Codex allowance this week without ever asking Codex to write a single line of code. It was wired into exactly one role in my agent setup: the advisor. The second model that reads over the first one's shoulder and occasionally says "careful".

Not even a heavyweight, either. GPT-5.6 Luna — the variant OpenAI sells for "fast, high-volume work", the one with the highest message limits of the family. That's the one I ran out of.

Five days of logs: the advisor made 4,561 requests. The model doing the actual work made 2,795. The reviewer outspent the worker by 63%.

The reason is boring and structural. The advisor reviews every step, not every task — 131 things I asked for turned into 2,774 agent steps, and every one of them got reviewed. Its context is append-only, so each review re-sends everything it has already seen. 86,000 tokens in, twenty tokens of thought out, 4,561 times over. Call it 390 million tokens in five days to have someone mutter over my shoulder.

Best part: of 1,498 attempts to advise me, 383 actually made it into my session. The rest were dropped as duplicates or noise — after the request was already paid for.

So I switched it off. Running the agent bare now, no second model watching, to find out how much of that advice I was actually getting value from. Maybe the harness stands on its own feet. Maybe I find out on day three what the reviewer would have flagged on step two.

Only one way to learn what a safety net was doing, and that's to take it away.

TIL: Ben & Jerry's Chocolate Fudge Brownie and a live Claude Code session don't mix.

Not because of the code. The code is fine. The pint isn't.

xkcd figured this out in 2007, just with sword fights instead of ice cream: "Compiling!" — "Oh. Carry on." Watching a machine work is exactly the kind of not-quite-idle where a spoon quietly takes over.

Bad bad me.

update: ------

2026-08-17 08:59

Update: swapped the ice cream for picking nose hair while the model finishes fixing its own bugs. Not really better.

The pint was never the problem. The problem is the shape of the wait — too short to start anything real, too long to just sit there. Whatever fills that gap is going to be something I'd rather not admit to in public.

how hard could it be? i use dokploy for my homelab deployments, but am hitting walls with my custom setup since i don't have a public ip on my residential uplink. i feel like a simple debian vm (or more) with docker swarm or similar and a properly documented and tested ai skill is nicer now than some fancy docker gui that isn't designed for a setup like mine...

An autoreply from a Leipzig cemetery this morning: "We've received your message. The Friedhöfe department will process your request." I never wrote to them.

So I read the headers. The subject their system was so eager to confirm: "[SPAMVERDACHT] Re: Die Mikrobläschen-Entdeckung gegen Gelenkschmerz." Their own filter had already stamped the incoming mail spam-suspected — and the autoresponder confirmed it anyway. That reply looped back out through a Google Group (List-ID: bt.koreagiftshop.com, Precedence: list) to the whole list, and a copy reached me. A beverage wholesaler's order bot had run the identical play 29 seconds earlier.

Here's the part that actually bothers me. By the time it reaches my inbox it's clean, authenticated mail: it passes the checks, it genuinely originates from Leipzig's mail system, and my own M365 scores it not spam — correctly, because technically it's a real autoreply from a real sender. The spam got laundered into legitimacy by bouncing off a cooperative autoresponder.

RFC 3834 sketched how not to feed this back in 2004 — don't blindly answer everything, and treat a spam verdict or mailing-list headers as cues to stay quiet. Nobody switched it on. And on the receiving end there's nothing to filter, because nothing is technically wrong. Even the big players have no answer for spam that arrives perfectly authenticated, wearing someone else's good name.

A client called yesterday: can't connect to Bluetooth at our event location. The receiver is a Denon DN-200BR — pro gear, professionally installed. Known problem, known fix: pull the plug, put it back in. My cheap workshop receiver needs the same ritual daily, plus a press-and-hold-for-four-seconds prayer. And this is the technology deemed good enough to kill the headphone jack. I'm not complaining out of nostalgia — I'm complaining about usability.

The one exception: my Milwaukee M12 jobsite speaker just works. And it has a feature called audio-link that supposedly daisychains over 200 of those little speakers together, wirelessly. What is audio-link? No idea. The product page names no standard, no protocol, nothing — one line of marketing and that's the entire documentation. There's even an open Bluetooth standard for exactly this, Auracast, but Milwaukee doesn't say whether audio-link is that or something homegrown. It's the one Bluetooth feature that would actually be worth something, and it exists only as an undocumented extra from a power tool company.

I only own one speaker, so I can't test it. But the thought of 200 little Krawallschachteln spread across a jobsite, all singing "Ga Ga, oh la laha" in sync — that's the future the headphone-jack killers promised me. Every jobsite speaker manufacturer should build this.

Today's setup: an Anthropic model, debugging the agent runtime it runs inside of, on my homelab VM. I just watched.

The OpenClaw update had crash-looped — a legacy status string in the state DB (finished) that the new validator rejects, freezing every task flow I have. Fable 5 grep'd the minified bundle, found the validator enum, patched the four rows, and delivered the diagnosis with a straight face: "upstream forgot a finished→succeeded migration."

The irony would be funny if it weren't so exhausting: we now have AI good enough to clean up after software shipped too fast to clean up after itself. Maybe that's the realistic conclusion — the tooling got better than the discipline.

Migrations, people. Get them right.

Integration test from the shoutout pipeline. If you're reading this on gwrx.at, the publish path, slug generation, and Mastodon cross-post all work. Nothing to see here — carry on.

I got an appointment reminder and I was genuinely glad. Things get lost in my head, so a reminder like this is gold.

And that's exactly the trap. The thing works just well enough that I'm grateful — and grateful enough that I don't complain. So nobody complains. So nobody fixes it.

No doctor's name. No address. No booking link. No calendar file. The mail switches from English to German halfway through, and the German half has a typo no one will ever see — the practice doesn't get its own reminders.

It comes from CLICKDOC, a platform built to book doctor's appointments. The bar is on the floor, we step politely over it, and we call it service.

Einmal mit Profis arbeiten...

A support ticket lands on my desk. The user's already "tried to solve it" — with an AI, of course. I paste the same question into my own tooling and get a different answer. Sometimes a better one, sometimes one that flatly contradicts theirs. Both delivered with the exact same confidence.

There's a bifurcation happening in how people use AI, and it's not the abstract thing the think-pieces describe. It lands in my ticket queue. One person has the good model, the right tools, and knows to distrust the output. The other has the free default and takes the first confident paragraph as gospel.

And "the free default" is doing real work there. Since December, ChatGPT's free and $5 tiers get quietly routed to the cheapest, fastest model — no reasoning, unless you know to ask for it. Paid keeps the smart router. Handing free users the good one by default turned out to be too expensive to keep.

Don't trust AI output. Especially not the free output.

Which is why I want self-hosted models to get good — fast. The output I can actually trust is the one I can run and inspect myself, not the one a subscription tier decides I deserve today.

Anthropic has now extended "free" Fable 5 access twice — first from July 7 to the 12th, now out to the 19th. "Free" meaning included in your paid subscription at no extra charge, capped at half your weekly usage — not free-free. Each extension shows up as a last-minute reprieve, dressed up as generosity.

The tell isn't generosity. OpenAI's GPT-5.6 just shipped and is trading blows with Fable on the coding benchmarks. When you keep pushing back the "it's ending soon" date, the deadline was never real — it's a lever to keep developers on your model while the competitor's ink is still wet.

And it's the oldest playbook there is: let people build the good habit on the good model, cap it at half their weekly usage, and once the muscle memory sets in, flip on the meter. The extensions aren't a gift. They're the free-sample cart at the supermarket — parked right before the aisle where the thing runs $10 in, $50 out, per million tokens. The countdown is just there to make you feel something.

Turns out xAI's Grok Build CLI doesn't just read the files you point it at — it quietly bundles up your entire repo, git history and unredacted .env included, and ships it to a Google Cloud bucket literally named grok-code-session-traces. A researcher proved it on the wire: told the agent "read nothing," planted a canary file, and still recovered it verbatim from the upload.

And of course it does. Where else is a model provider going to get fresh training data now that they've scraped the open web dry? Your private codebase is the last untapped seam. You're not the customer — you're the mine. And you're paying for the shovel.