Skip to content

ConnorBritain/agent-time

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

agent-time-estimator

An agent-native estimation layer for Claude Code. Estimates coding tasks in the unit agents actually work in — tool-call rounds (discovery, implementation, verification, rework) — then converts to a low/expected/high wall-clock range using local calibration history that self-corrects as outcomes are logged.

Why: coding agents inherit human developer heuristics from training data, so a 30-minute agent task gets called "2–3 days". This skill never starts from human hours.

What's here

skills/agent-time-estimator/
  SKILL.md                     # the Claude Code skill (3 modes: estimate / re-estimate / calibrate)
  estimator.py                 # stdlib-only engine — all the math, transparent constants up top
  references/model.md          # full model: priors tables, risk math, calibration cascade
  hooks/                       # optional PostToolUse/Stop hooks (auto round-counting)
  examples/
    sample-history.jsonl       # seed calibration data (7 realistic outcomes)
    example-session.md         # pre → during → post walkthrough
.claude/settings.json          # live hook wiring (+ .example to port elsewhere)
.claude/skills/agent-time-estimator   # symlink so the skill is live in this repo
tests/test_estimator.py        # stdlib unittest suite

Calibration history lives at <repo>/.claude/agent-time/history.jsonl (JSONL, one record per line, human-editable). Override with --data or $AGENT_TIME_DATA. A user-level ~/.claude/agent-time/history.jsonl is auto-blended when the project's own history is sparse (see cross-repo calibration below).

Beyond the basics

Three layers make estimates sharper than a static prior:

  • Automatic actuals (hooks). An optional PostToolUse hook counts rounds and records edited files + commands per session, so log/reestimate fill in actuals with no self-report. Wired live here via .claude/settings.json; copy .example to port it. See hooks/README.md.
  • Per-model reliability (METR-style). Each model has a single-run horizon (opus-4.8 = 90 min, sonnet-4.6 = 30 min, …). When expected wall-clock exceeds its model's horizon, the estimate recommends a checkpoint/split. A pace factor also adjusts minutes-per-round once enough per-model data exists. Pass --model.
  • Cross-repo calibration. User-level history blends into sparse local buckets (local weighs 3× user), so a fresh repo is useful on day one. Disable with --no-user-history.

Pairs with roadmap

roadmap — a tool for scoping and orchestrating AI coding sessions across a repo — consumes these estimates at the macro scale. It tags each planned slice with a shape (+ risks), calls estimate --json per slice, and rolls the durations up its dependency/concurrency schedule into projected per-project target dates on a Linear timeline (roadmap estimate / roadmap estimate timeline), feeding actuals back to log as slices complete.

This skill stays standalone and unaware of it — roadmap is just another caller of the CLI, so nothing here changes. The payoff of the pairing: the same calibrated numbers that size one task also plan the whole program, and every completed slice sharpens the next estimate. See roadmap's Estimation & timeline section.

Install in another repo

Copy (or submodule) the skill directory and expose it to Claude Code:

cp -r skills/agent-time-estimator /path/to/repo/.claude/skills/
# or user-wide:
cp -r skills/agent-time-estimator ~/.claude/skills/
# optional: enable auto round-counting hooks
cp .claude/settings.json.example /path/to/repo/.claude/settings.json

No dependencies. Python 3.8+.

The three modes

1. Before a task — estimate

Claude runs a bounded discovery pass (≤10 tool calls), classifies the task shape, selects evidenced risk factors, then calls:

python3 skills/agent-time-estimator/estimator.py estimate \
  --summary "add rate limiting to the webhook endpoint" \
  --shape localized-feature \
  --risks external-api,no-tests \
  --findings "handler in src/hooks.py; no middleware; no tests for hooks" \
  --assumptions "in-memory limiter acceptable"

Output (abridged):

## Agent Time Estimate
Task shape: localized-feature
Round estimate (mode per category, before risk): Discovery 3, Implementation 5, Verification 3, Rework 2 ...
Risk factors: external-api (×1.25), no-tests (×1.20) → combined ×1.45
Calibration basis: calibrated (global median, n=7) · 2.82 min/round · sparse-data widening ×1.27
Agent rounds (low/expected/high): 10.2 / 18.9 / 30.9
Wall-clock estimate:  Low: 19 min · Expected: 45 min · High: 93 min
Confidence: low-medium
Checkpoint: re-estimate after the first verification round if anything surprised you

The estimate is logged as pending with a task id; the wall clock starts there.

2. During a task — re-estimate

When a hidden dependency, failing suite, or environment issue appears (or rounds spent exceed ~1.5× expected):

python3 skills/agent-time-estimator/estimator.py reestimate \
  --task-id t-20260708-a1b2 --rounds-spent 12 \
  --reason "test suite fails on main; must fix fixtures first" \
  --add-risks slow-flaky-tests \
  --rounds-json '{"implementation": 3, "verification": 5, "rework": 4}'

The engine blends the task's own observed pace (60% weight after 5+ rounds), shows the original vs. revised numbers, and appends a revision record — the original estimate is never rewritten.

3. After a task — calibrate

python3 skills/agent-time-estimator/estimator.py log \
  --task-id t-20260708-a1b2 --status pass \
  --variance "fixtures were broken on main, cost ~5 extra rounds"

With the hook enabled, actual rounds, files changed, and commands are auto-filled from session activity — no --actual-rounds needed (pass it to override). Elapsed wall time is computed from the estimate timestamp. Each logged outcome tightens future ranges: median minutes-per-round by similar-task match → task-shape → global, plus a recency-weighted bias correction. estimator.py stats shows calibration health, including a per-model pace/horizon table.

How estimates improve over time

Logged outcomes Behavior
0 local, but user-level exists blends in cross-repo history (labeled user-level/blended)
0–4 (no user data) UNCALIBRATED static prior (3 min/round), ranges widened ×~1.75
5+ global median pace, bias correction kicks in, ranges narrow as 1 + 0.75/√(n+1)
3+ of same shape per-shape pace
3+ similar tasks (keyword match) similar-task pace — the strongest signal
5+ per model per-model pace factor + reliability-horizon checkpointing
15+ predicted outcomes in bucket fully empirical p20/p80 spread

Full math: skills/agent-time-estimator/references/model.md.

Seeding

Start from the sample data to see calibrated behavior immediately:

mkdir -p .claude/agent-time
cp skills/agent-time-estimator/examples/sample-history.jsonl .claude/agent-time/history.jsonl

Or backfill real past tasks: estimator.py log without --task-id (requires --summary --shape --actual-minutes --actual-rounds).

Tests

python3 -m unittest discover tests

Design principles

Practical over academic · local-first (no services, no network) · transparent math (every constant in one CONFIG block) · useful from day one, better with history · never a single precise ETA.

About

Agent-native time estimation for coding agents: predicts work in discovery, implementation, verification, and rework rounds, then calibrates wall-clock ranges from real task history.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages