Problem
When measuring task executor launch latency end-to-end, we need to know how long the aictrl CLI itself takes to initialise — from process start to "ready to send the first instruction to the model". Currently the only timing signal we have post-startup is session_start, but it has no duration field, so consumers (the executor entrypoint, BigQuery dashboards) can't compute CLI startup overhead.
The session_start event is emitted at packages/cli/src/cli/cmd/run.ts:671, which fires after:
- Bun runtime + import graph load
- yargs handler entered
bootstrap() → InstanceBootstrap() (Plugin.init, LSP.init, FileWatcher.init, etc.)
- Session create / fork / share
…and before the first prompt dispatch (sdk.session.prompt()). That's exactly the boundary we want for "CLI ready". We just can't currently measure how long getting there took.
Why it matters
We're trying to drive task executor launch latency toward <1s aspirationally. Today P50 launch is ~104s (Cloud Run Jobs gen2 microVM boot dominates), and once we eliminate the cold-start path, the next bottleneck will likely be CLI startup. We need this number to (a) baseline it, (b) decide whether Bun import time / plugin init is worth optimising, (c) track regressions over time.
Proposed change
- Capture a process-start timestamp at the very top of the CLI entry point (before any other imports if practical, or as the first statement in the entry script).
- Add a
cliInitMs field to the session_start event payload, computed as Date.now() - processStartTime.
- Update
EVENTS.md to document session_start semantics precisely:
Fires after plugin/LSP/session initialisation, before the first prompt dispatch — represents the moment the CLI is ready to send the first instruction to the model. cliInitMs measures process start → this event.
Acceptance criteria
Files
packages/cli/src/cli/cmd/run.ts — line 671 emit call
- The CLI entry point file (top of process) — capture timestamp
EVENTS.md — documentation update
Out of scope
- Optimising Bun import time / plugin init (separate investigation, gated on having this measurement)
- Measuring time after
session_start (first model token, etc.) — that's user workload, not CLI startup
Related
- aictrl-dev/aictrl#883 — Bootstrap bundle caching (executor side)
- aictrl-dev/aictrl#895 — Tiered bootstrap (executor side)
- A companion executor-side instrumentation issue will be filed in aictrl-dev/aictrl that consumes
cliInitMs from this event.
Problem
When measuring task executor launch latency end-to-end, we need to know how long the
aictrlCLI itself takes to initialise — from process start to "ready to send the first instruction to the model". Currently the only timing signal we have post-startup issession_start, but it has no duration field, so consumers (the executor entrypoint, BigQuery dashboards) can't compute CLI startup overhead.The
session_startevent is emitted atpackages/cli/src/cli/cmd/run.ts:671, which fires after:bootstrap()→InstanceBootstrap()(Plugin.init, LSP.init, FileWatcher.init, etc.)…and before the first prompt dispatch (
sdk.session.prompt()). That's exactly the boundary we want for "CLI ready". We just can't currently measure how long getting there took.Why it matters
We're trying to drive task executor launch latency toward <1s aspirationally. Today P50 launch is ~104s (Cloud Run Jobs gen2 microVM boot dominates), and once we eliminate the cold-start path, the next bottleneck will likely be CLI startup. We need this number to (a) baseline it, (b) decide whether Bun import time / plugin init is worth optimising, (c) track regressions over time.
Proposed change
cliInitMsfield to thesession_startevent payload, computed asDate.now() - processStartTime.EVENTS.mdto documentsession_startsemantics precisely:Acceptance criteria
session_startNDJSON event contains a numericcliInitMsfieldcliInitMsaccurately reflects time from process start to event emission (verifiable by manual timing)EVENTS.mddocuments the boundarysession_startrepresents and the meaning ofcliInitMsFiles
packages/cli/src/cli/cmd/run.ts— line 671 emit callEVENTS.md— documentation updateOut of scope
session_start(first model token, etc.) — that's user workload, not CLI startupRelated
cliInitMsfrom this event.