Skip to main content

time

Per-step time tracking that gives agents a way to recalibrate scope mid-run from elapsed-vs-estimated deltas.

Why

LLMs inherit human estimation bias from training data — engineering tickets and post-mortems systematically underestimate, so when a plan says "2-day task" an agent tends to pace itself accordingly even when the underlying work is hours. The time command lets the agent ground its pace in real elapsed time and act on the delta. The companion directive 045-upstream-time-awareness.md tells agents when and how to use it.

Subcommands

SubcommandPurpose
planRecord the current plan with per-step estimates
start <step>Mark the start of a step
finish <step>Mark the finish of a step
statusShow estimate-vs-elapsed deltas and the pacing signal

Usage

Record a plan

era-code time plan --steps '[
{"name":"investigate-auth","estimate_minutes":45},
{"name":"implement-handler","estimate_minutes":90},
{"name":"write-tests","estimate_minutes":60}
]'

Recording a plan resets the event log, so the latest call is always the active plan.

Mark step boundaries

era-code time start investigate-auth
# ... do the work ...
era-code time finish investigate-auth

Step names must match the names recorded in the plan exactly.

Read pacing signal

era-code time status

Sample output:

Time-Aware Scoping Status
──────────────────────────────────────────────────

Plan recorded: 5/6/2026, 11:34:51 AM
Total estimate: 195m
Total elapsed: 12.4m (15.7× faster)

Steps:
✓ investigate-auth est 45m / actual 4.2m (10.7× faster)
→ implement-handler est 90m / running 8.2m
· write-tests est 60m / not started

Pacing signal: Running far ahead of plan. You may consolidate remaining steps,
expand scope, or skip checkpoints sized for a slower trajectory. Update priors
from evidence, not from the original estimate.

Options

OptionApplies toDescription
--steps <json>planJSON array of {name, estimate_minutes}
--quiet / -qallSuppress human-readable output
--jsonallOutput structured JSON for programmatic use

Pacing Signal

The status output classifies the overall ratio (estimate / actual elapsed):

SignalThresholdMeaning
far_aheadratio ≥ 3Running ≥3× faster than estimated
on_pace0.5 ≤ ratio < 3Within 2× of plan in either direction
running_longratio < 0.5Running ≥2× slower than estimated
unknownno elapsed timeInsufficient data to derive a signal

[!TIP] The signal is meant to drive scope decisions, not produce a timesheet. When far_ahead, agents are explicitly permitted to consolidate steps or expand scope. When running_long, they should pause and surface the disconnect rather than silently extending.

Storage

Per-step time data is persisted under .era/runtime/:

FilePurpose
.era/runtime/current-plan.jsonMost recent recorded plan
.era/runtime/events.jsonlAppend-only log of step start/finish events

The directory is added to .gitignore automatically by era-code init.

Optional Telemetry

If the environment variable ERA_TIME_TELEMETRY_URL is set, every plan and event is also POSTed there as JSON (best-effort, 2s timeout, errors swallowed). This lets era-code-agent runtime and era-code-manager consume the same signal without polling the workspace filesystem.

export ERA_TIME_TELEMETRY_URL=https://agent.example/api/time-events

Payload shapes:

{ "kind": "plan", "plan": { "recorded_at": "...", "steps": [...] } }
{ "kind": "event", "event": { "ts": "...", "step": "...", "event": "start" | "finish" } }

Use Cases

  • Mid-run recalibration: Agents read status between pipeline steps and rescope when running far ahead, or escalate when running long.
  • Cross-system telemetry: Set ERA_TIME_TELEMETRY_URL to fan events to era-code-agent / era-code-manager for centralized observability.
  • Standalone usage: Works without any backend — the JSONL log is itself a complete record of run pacing.