Skip to main content

Side Execution

Side execution is fire-and-forget or background work spawned alongside a main agent run — not blocking the main loop, not owning the chat conversation, but still traceable and observable.

Backed by the server's SideExecutionManager and the sideExecution.cli surface.

When side execution fits

  • Parallel scouts. The main agent asks three side tasks to search the codebase, read dependencies, and check recent commits — then uses whichever finish first.
  • Async enrichment. Kick off a code-map rebuild or a long eval while the main agent continues.
  • Background analyses. Security scan, license audit, performance regression check — interesting but not blocking.
  • Pre-warming. Preload memory or retrieval results before the agent needs them.

Don't use side execution for work the main agent needs a result from before proceeding — that's a subagent, which is synchronous and typed.

The three flavours

FlavourSemanticsWhen
Fire-and-forgetSpawn, don't wait, don't read resultsLogging, analytics, pre-warming
JoinableSpawn, continue, later await the result if still neededScouts, speculative work
StreamingSpawn, receive partial results as events while the main loop continuesLive indexing, long-running retrieval

Spawning

// fire-and-forget
await ctx.side.spawn({
task: "reindex-codemap",
inputs: { root: "./src" },
});

// joinable — grab a handle, await later
const handle = ctx.side.spawn({
task: "security-scan",
inputs: { paths: ["./src", "./package.json"] },
joinable: true,
});

// ... later, when we need the result
const report = await handle.join({ timeout_ms: 30_000 });

// streaming
const stream = ctx.side.spawn({
task: "deep-code-search",
inputs: { query: "..." },
streaming: true,
});
for await (const hit of stream) {
// process as they arrive
}

Lifecycle and cancellation

  • Side executions inherit the parent run's trace — the event log nests their events under the parent's.
  • They're cancelled automatically when the parent run ends (unless explicitly promoted to persistent — rare).
  • They have independent budgets — a side task can't consume the parent's token / time budget.
  • A side task may spawn its own tools and LLM calls, but may not spawn subagents by default (keep-it-simple rule; relaxed per-project if needed).

Observability

Every side execution shows up in:

  • The flow view as a branch off the parent run.
  • The event log with its own run ID.
  • The trace UI nested under the spawning phase.

You can re-run a side task in isolation via replay the same way you would a subagent.

Side execution vs. subagent

AxisSide executionSubagent
Blocking?No (unless you join)Yes
Has its own reasoning loop?Yes, but lightweightYes, full
Memory accessRead-only to parent's memoryCan write to parent's memory (scoped)
CostLow-moderateModerate-high
Good forSpeculative / parallel workDecomposition of a required task

Authoring a side-execution task type

Most of the time you use built-in task types. If you need a custom one:

  1. Define the task in .codebolt/side-tasks/<name>/task.yaml.
  2. Implement the handler (same shape as a lightweight skill).
  3. Register; the server picks it up on reload.

See also