by Martin Monperrus, Evita Stenqvist Tags:

TLDR: coding agents estimate durations in human time, and execute in machine time. The gap is one to three orders of magnitude. We call this the anthropocentric time bias, and it is a systematic, measurable, and rather funny failure mode.

The phenomenon

Ask Claude Code to plan a feature. You get something like this:

Phase 1: schema migration (3-4 days)
Phase 2: API endpoints (1 week)
Phase 3: frontend integration (1-2 weeks)
Total: 3-4 weeks

Then you type “go”, and Claude is done in eleven minutes. 🕚

This happens constantly. Eivind Kjosbakken documented it precisely in Why Claude Code Time Estimates Are Poor (Towards Data Science, August 2026): Claude estimated “3-4 weeks of work” for a chatbot feature that took a single day. Clinton Stark reports the same ratio in Stark Insider (May 2026): a phase Claude priced at “6-8 hours of coding time” finished in about 10 minutes, and a single 39-minute autonomous run produced 8 merged feature branches and 100+ tests.

That is a 40x error. Per Claude’s own arithmetic, you do months of work in an afternoon.

Why: two independent causes

The bias is not one bug. It is two.

1. The training data is human. Every “this took me two weeks” blog post, every sprint estimate in a JIRA export, every “estimated effort: 5 story points” in a design doc, every software engineering textbook — all written by and about humans typing at 60 words per minute. Pre-2022 GitHub is a corpus of exclusively human throughput. Claude learned what a feature costs, in the only currency that existed at the time: human-weeks. It then quotes you that price without converting the currency.

2. The model has no clock. This is the deeper one. A transformer’s positional encoding represents token order, not elapsed wall-clock time. There is no proprioception of inference speed. The model knows, propositionally, that “writing an API takes days”; it has zero experiential access to the fact that it just wrote one in 90 seconds.

The second cause is why the first cannot be fixed by simply saying “you are fast, adjust your estimates.”

The evidence

The research literature caught up in 2025-2026, and it is unambiguous.

The fix

Problem A — estimation (the anthropocentric bias): “3-4 weeks” for eleven minutes of work.

Problem B — perception: the agent can’t feel wall-clock elapsing during a session. Turn 3 and turn 30 look the same; a 2-minute boot and a 2-hour RPC scan are both “one tool call”.

Fix by Prompting (cheap, partial)

  1. Ban the unit (A). Estimate in files touched, tool calls, tokens, blast radius. This works because you remove the projection the bad prior lives in, rather than asking the model to correct it.
  2. Give the exchange rate explicitly (A). “You produce ~100 lines/minute and ~1 tool call/second. A task a human prices at 1 week is ~10 minutes for you.” A concrete numeric anchor beats “you are fast”.
  3. Name the granularity (B). “boot takes ~2 minutes and a sweep is milliseconds; conclude nothing from a log read 30 seconds after a restart.” Per-operation latency constants in CLAUDE.md are the single highest-value thing for B, because they’re unguessable and repo-specific.
  4. Require a measurement, not a guess (B). “Before concluding a process is hung, print date and compare against the timestamp in the log line.” Replaces a hallucinated clock with tool I/O.

Fix by Harnessing (what actually holds)

Prompting decays across a long context; the harness re-asserts every turn. Mirror token awareness: the only reliable signal is the one injected on every single turn.

  1. Inject elapsed time per turn. Each turn emits “session elapsed: 14m22s · last tool: 340ms · wall since your previous message: 91s”. This is the closest thing to temporal proprioception you can retrofit — three numbers, every turn, no reasoning required. Easy with hooks (UserPromptSubmit/PreToolUse)
  2. Timestamp every tool result. Wrap Bash so stdout carries start/end/duration. The model then has a lived distribution of how long things take in this repo, instead of a trained-on prior about how long things take for humans.
  3. Make waiting non-polling by construction. Don’t rely on the model resisting the urge to check — give it a primitive that makes checking unnecessary: background until ; do sleep N; done; notify, plus a scheduler that wakes it on completion.
  4. Log durations into the repo (A’s only durable fix). Append task → wall-clock to a file, feed the last N back as context. Self-correcting, and it tracks the model getting faster — no static prompt constant survives a model upgrade.

Implications

This is not a cosmetic annoyance in a plan document. A wrong internal cost model is a wrong policy. The agent acts on it.

1. It kills long-horizon work. An agent’s decision to continue or to stop is a comparison: remaining effort vs. remaining budget. Corrupt the numerator by 40x and the comparison always returns “stop”. Concretely, this is what you see:

The perverse part: the tasks that get truncated are exactly the valuable ones. Small tasks are estimated in hours and get done. Big tasks are estimated in weeks and get declined. The bias is a filter that selectively removes the ambitious work — precisely the work where agents have the largest advantage over humans, since their marginal cost per additional file is near zero and ours is not.

2. It breaks autonomy, by manufacturing false checkpoints. Every “this is a big one, want me to continue?” is a round trip to a human. Round trips are the scarce resource in agentic work: they cost minutes of your attention, they force a context switch on you, and they are where sessions die. An agent that overestimates its remaining work generates these interrupts constantly — not because it is uncertain about what to do, which would be a legitimate reason to ask, but because it is wrong about how expensive it is. This is an interrupt with zero information content. And it is self-reinforcing: the human, seeing “1-2 weeks”, says “ok, just do Phase 2” — ratifying the agent’s fictional decomposition and paying for one more round trip.

See also