← INDEX
document
visual explainer
plugin
temporal-awareness · v0.1.0
variant
Escapement — navy & bone
companion-to
README.md
series
really claude code · agent autonomy
◷ really claude code

temporal-awareness

Claude thinks in human developer-days. It works in agent-minutes. This plugin teaches it the difference — and grounds the correction in its own measured history.

Ask Claude how long a task will take and it answers "one to two days" — an estimate borrowed from human developers. But when the agent does the work, the part that dominates that estimate collapses to minutes. The gap is one to three orders of magnitude, which makes planning with agents nearly useless. temporal-awareness fixes the reasoning, then replaces the guess with data Claude was already generating and never looked at.

01The wrong reference class

why the estimates are off by orders of magnitude

Claude's instinct for "how long" is trained on an enormous corpus of human-written estimates — Jira tickets, blog posts, retros, textbooks — all measured in developer-days. That world assumes a person types the code, context-switches between meetings, looks up docs, gets tired, and works an eight-hour day.

An agent pays almost none of those costs. The reading, writing, and wiring that dominate a human's estimate compress dramatically. So the model isn't computing a wrong answer — it's fluently echoing the wrong reference class. The result, on a log scale:

1 min 10 min 1 hr 8 hr 1 day where agent work actually lands "1–2 days" ≈ 50–100× overestimate

the same task, two reference classes · log-spaced axis

02Split what collapses from what doesn't

the core move — accurate, not just smaller

The fix is not "say a smaller number." That would just replace one wrong answer with another — because some things genuinely don't compress. The move is to decompose every estimate into two buckets, and treat them completely differently.

collapses →

Agent execution

  • reading & navigating the code
  • writing and wiring the change
  • writing tests in the same loop
  • local iteration to green

Sized in the agent's timescale — seconds to minutes for most bounded tasks.

doesn't collapse →

Gates

  • CI pipelines, full test suites
  • builds, deploys, model training
  • human review & sign-off
  • external / calendar waits

Runs at its own pace no matter how fast the agent is. On the machine's clock, or yours.

the symmetry that keeps it honest Under-counting a real 20-minute CI run is just as wrong as over-counting typing time. A skill that only ever shrinks estimates would confidently claim a 50-million-row training job takes fifteen minutes. The two-bucket split is what prevents the correction from over-correcting.

03The data was already there

Claude's own /goal completions, hiding in the transcripts

Here is the part that turns a reasoning trick into a calibrated instrument. Every time you run /goal, Claude Code records the completion in the session transcript — including an authoritative duration field, goal_status.durationMs, computed by the harness itself. It was found by forensic search through transcripts and debug logs; the harness never advertises it.

Raw wall-clock is a trap — inflated 5–25× by overnight and idle gaps. But completed goals (met == true) are clean, because a goal only completes while it's being actively worked. The result is a small corpus of real durations — and it confirms the whole thesis:

~10 min
median completed goal
3.5–60 min
full observed range
0 / dozen
goals measured in "days"
distribution · ~13 completed goals median ≈ 10 min
1 5 2 2 2 1 <5m 5–10 10–20 20–30 30–45 45–60 minutes per completed goal median ~10m a "1–2 day" estimate would sit ~50 charts to the right

The corpus doesn't just correct the bias — it proves it. Claude's real tasks take minutes.

04From transcript to prior

a SessionStart hook, running while you're not looking

Keeping the corpus fresh has to be cheap, or it can't run at session start. So the hydrate is incremental (only re-scans transcripts touched since last run — ~0.1s steady state) and backgrounded (never blocks startup). It mines new completions, classifies each goal once with a stripped-down headless Haiku call, and pre-digests everything into a compact summary the skill reads instead of the raw rows.

temporal-awareness hydrate pipeline At session start a background hook mines authoritative goal durations from the transcripts, classifies each goal once with a Haiku call, writes a compact bucketed summary, and the skill reads that summary as a prior when estimating. session start · background · incremental transcripts ~/.claude/projects goal_status.durationMs hydrate_corpus.py mine met==true goals exclude idle · dedup claude -p · haiku bucket each goal cached · one-time goal-measurements one row per goal full prompt + confounds summary.md Overall + per-bucket median · p10–p90 · O(1) agent-time-estimation skill reads the summary as a prior scan new label write aggregate read

flow: top → bottom · everything downstream of the harness's own duration field

05A prior, not a lookup table

the strong signal is scale — the medians are soft

The temptation is to treat a bucket's median as the answer. The skill is explicit that this is wrong. The corpus's strong, trustworthy signal is scale: this work is minutes, not days. The per-bucket medians are much softer, because the categories are coarse — a single bucket holds wildly different tasks.

bucket: bugfix  ·  median ~7 min  ·  but look at the spread
median ~7m ~2 min hours same bucket · same median · not remotely the same task
bugfix · instance A
an off-by-one

Diagnosed, one line, tests already cover it. Sits at or below the low end — near p10.

bugfix · instance B
"prod DB got dropped"

Recovery, verification, blast-radius checks. Sails well past p90 — the median is nearly uninformative here.

So the skill reads a bucket's spread first, median second, then reasons about this task's context — scope, severity, blast radius, ambiguity — and places the estimate on, or beyond, the range. A wide p10–p90 is not noise to average away; it's the signal that context, not the median, decides the number.

Bugfixes here have typically run ~7 min — but a dropped prod DB is a different animal; recovery and verification push this well past that. An off-by-one would be under it. — the shape of a well-formed estimate

06Closing the epistemic gap

the family resemblance to context-awareness

There's a recurring pattern across the agent-autonomy plugins: Claude Code logs a great deal about its own operation, and Claude — the model inside it — rarely looks. Context budget sits in the status line the model never reads. Goal durations sit in transcripts the model never mines.

temporal-awareness closes that loop for time the same way context-awareness does for context budget: it takes a signal the harness already produces and hands it back to the model in a form it will actually use. The estimates stop being a borrowed human intuition and start being grounded in Claude's own measured history.

also handled A wall-clock deadline — "can we have this done by 1pm?" — can't be answered from an estimate alone, because Claude doesn't inherently know the current time. The skill fetches the real clock first, then does the arithmetic: now + execution + critical-path gates vs. the deadline, keeping work-time separate from calendar-time.

The interesting part isn't that Claude now quotes a smaller number. It's that the number is finally about the right thing — the agent's own execution, measured against the agent's own history, with the gates that don't collapse named honestly beside it. Accurate, not just smaller — and, increasingly, learned rather than assumed.