Most of my code is written by an agent now. I bill people for it, and I can’t tell you how long anything took. I suspect most agencies can’t either. I’ve been trying to fix that.
METR ran a controlled study and found that AI made tasks take 19% longer, not shorter, while the developers using it reported feeling faster. The unit we bill by, the hour, is the one thing about our own work we understand least. That worries me. I invoice people, and I'm billing them in a unit I can't even measure on myself.
Contractors and agencies bill hours. I've come to think hours are a fiction everyone agrees to maintain. One survey across consulting, legal, and accounting found that 22% of professionals record less than 70% of their time, and the leakage isn't random: email, phone calls, and meetings bleed the most, because they don't feel like deliverables. The person doing the work writes a story in their head, "reviewed the contract for Acme." The person billing needs a number, a client code, a matter, a rate. The gap between the story and the number is where revenue quietly dies. Timesheets are uncompensated labor, and a brain trained by hourly billing to ask "does this earn?" of every minute correctly refuses to do uncompensated labor.
So we automate, hopefully. Two flavors, and both feel wrong for what I do now.
Automatic tracking becomes surveillance: screenshots, keystroke logs, idle flags beamed to a manager in real time. Toggl, to its credit, refuses to ship that. Their own honest framing is that manual timers give you control and data quality, while automated capture gives you coverage and less friction, and there is no winner. And then agentic work breaks at both, at least from where I sit.
The agent runs for three minutes doing real work, calling tools, reading files, while I'm on another tab. Whose time is that? A provider stalls mid-stream for thirty seconds. The stopwatch bills it. I don't think it should. It's a retry, not work. The timesheet was built for a world where a human typed and a clock ticked. Now the agent types and the human thinks, and I think the clock is measuring the wrong body.
I really like using Modal, as it frames the serverless problem cleanly. Utilization is output achieved divided by capacity paid for. The whole game is to not pay for idle: match provisioned supply to demand, scale to zero. Marc Brooker's line, quoted by Modal: cost scales with peak traffic, value scales with average traffic. The gap between peak and average is exactly what serverless closes.
What if we took that to the agency? The agent is the on-demand function. A turn is an invocation. Bill the invocation by duration. Human idle is scale-to-zero: it costs nothing by default. Human oversight is provisioned capacity: you opt into a block, idle and steering bill against it, the leftover rolls forward. You set the budget. The engine spends it.
The first version of this idea you reach for is "just auto-track everything." That's surveillance with a receipt. Pure automatic billing charges the minutes you spent, including the minutes that went nowhere. You walked away. You changed your mind. The agent did nothing useful. The stopwatch bills all of it.
What we ended up trying is almost the opposite. Measure automatically, but only commit a bill when the work landed. Two rules do most of the work.
Idle bills only when your next submit produces agent work. You sit and think for ten minutes, then send a prompt and the agent runs. That idle bills. You sit and think for ten minutes, then close the laptop. That idle bills nothing. I've come to think idle with no output is wasted, and it shouldn't be billable.
Steering bills only typing that actually reached the agent. You queue a follow-up while the agent runs, then revert it, re-edit, re-send. That bills once, at delivery. You queue it and delete it. That bills nothing. No agent outcome, no bill.
Bill forward progress, not process. That's the part I'm most sure about. The clock still runs. It only rings when something landed.
There's a third choice that matters more than it looks: we detect engagement, we don't demand it. A human-time window opens on your first keystroke after a turn, not on a Start button you'll forget to press. But a single stray key bills nothing. Only a real typing burst counts. So it's automatic, and it still respects that you have to actually be there. Nobody starts a timer. Everybody who bills was present.
The interesting part is how you stop the abuse without becoming a cop.
Token-normalized billing. Agent time per turn is output tokens divided by a reference tokens-per-second, plus real tool-execution time.
agent_ms = (output_tokens / reference_tps × 1000) + tool_ms
reference_tps defaults to 75, a frontier-model average. Two things fall out of that, and I think both are the point. A fast model and a slow model producing the same output tokens bill the same, so model speed can't move the bill, and a faster model no longer punishes the contractor. And a stall drops out by construction, not by policy. A stall emits no tokens. Token-normalized billing never counts it. I like that the abuse vector, a slow or queued provider inflating your invoice, gets closed by the math, not by a rule someone has to enforce. The real wall-clock stall time stays on the event for audit. It just doesn't bill.
Keystroke bursts. Steering is billed as the sum of typing bursts, not the wall-clock from your first keystroke.
burst = last_keystroke − first_keystroke, within a 3s gap
A single key is a zero-length burst. It bills nothing. Keys spread minutes apart bill nothing. Only sustained typing bills. Held keys collapse within 50ms, so you can't hold a key down to farm a burst. Human typing, varied keys and deliberate double letters, is unaffected. The gap is a knob: tighten it to make farming harder at the cost of splitting real pauses, loosen it to forgive longer thinking. We landed on 3s after some fiddling, and I'm still not sure that's the right number.
Billing at delivery, not submit. A queued steer is staged when you submit, but committed only when it actually enters the conversation. Revert it (alt-up) and the typing carries forward to your next send, so re-steering bills the original composition once, not twice. Dequeue it and never re-send and it bills nothing. The principle is the same as idle: no agent outcome, no bill.
State lives in a per-session sidecar, a JSONL file outside the session log, so it survives compaction. Everything rebuilds from it on reload. Stateless. The same log reconstructs the same totals across branches and restarts.
The receipt streams in. Each line unhides, then its values type out character by character with a blinking cursor, like an LLM token stream. The invoice for agentic work generates like agentic work. It's a small joke, but I like it. Print to PDF and the cursor hides.
A note on slop, because someone will ask. This was written with an agent in the loop, like most of what I ship now. I don't think the test for slop is whether AI touched it. I think it's whether a sentence says something or only gestures at saying something. We cut the em-dash litter, the three-beat lists, the "everything changed" pivots. If a paragraph could be deleted without losing the argument, we deleted it. That's the same standard I want to apply to the billing: if it didn't land, it doesn't bill. If it didn't say anything, it doesn't ship.
This is pi-ledger, an open-source extension for pi that meters agentic work and prints an invoice-grade receipt. It bills agent time per turn, stalls excluded, and human time as provisioned capacity you opt into.
pi install github:inloopstudio-team/pi-ledger
I'm not certain this is the right model yet. I'm fairly sure the old one is wrong, and this is the best guess I've got. The bet is that the next dev shops won't look like studios with timesheets. They'll look more like serverless platforms: on-demand agents, duration billing, scale-to-zero humans, and oversight you provision when you mean it. We'll see.
We call it the serverless agency. It's a dev shop that bills like compute, and I'm curious what happens when you run one.