From the 2026-06-10 review (deferred; the fix PR ships an approximation).
Docker measures timing.executeMs immediately after the runtime exits (pre-harvest); the k8s backend now approximates it as durationMs - harvestMs - uploadMs, which still includes pod scheduling + image pull + startup. The residual is documented on ExecutionBackend.execute, but the field has no precise cross-backend definition.
If usage analytics start consuming per-phase timing (agent/model attribution work), define the canonical semantics — e.g. have the harvest container measure runner wall-clock directly (it observes the exit-code file appear and could carry a startedAt from the runner wrapper) and report it in the result line.
Refs: services/sandbox/src/backend/kubernetes/k8s-backend.ts (assemble timing), backend/local-workspace-run.ts, backend/types.ts outcome-table doc.
From the 2026-06-10 review (deferred; the fix PR ships an approximation).
Docker measures
timing.executeMsimmediately after the runtime exits (pre-harvest); the k8s backend now approximates it asdurationMs - harvestMs - uploadMs, which still includes pod scheduling + image pull + startup. The residual is documented on ExecutionBackend.execute, but the field has no precise cross-backend definition.If usage analytics start consuming per-phase timing (agent/model attribution work), define the canonical semantics — e.g. have the harvest container measure runner wall-clock directly (it observes the exit-code file appear and could carry a startedAt from the runner wrapper) and report it in the result line.
Refs: services/sandbox/src/backend/kubernetes/k8s-backend.ts (assemble timing), backend/local-workspace-run.ts, backend/types.ts outcome-table doc.