Files
vercel__eve/research/session-network-hops.json
T

387 lines
16 KiB
JSON

{
"title": "eve session network hops",
"captured": "2026-09-11",
"baseCommit": "adb6beff622b274970d4e48b7178b7d44c11d456",
"workingTree": true,
"sdk": "@workflow/core 5.0.0-beta.50",
"evidence": "Source-derived operation inventory, not a latency benchmark. World, cache, replay, payload size, and authored integrations change request counts.",
"clocks": [
"HTTP request to first provider request",
"HTTP request to dispatch acceptance / returned Session identity",
"HTTP request to visible turn settlement"
],
"invariants": {
"sessionId": "original stream-owning run ID",
"ownerRunId": "current executor; changes on handoff",
"metadata": "{ sessionId }, accessed only when requested after resumption",
"startupHooks": "1 eve stable inbox + requested aliases + 1 SDK cancellation hook for the first turn"
},
"limitations": [
"Alias-only delivery cannot distinguish an unowned address from a handoff gap. Atomic handoff is an upstream requirement.",
"Rows name SDK operations, not a guaranteed count of lower-level HTTP retries or queue deliveries.",
"Authorization, sandbox, memory, telemetry and authored hooks must be measured for a specific deployed agent."
],
"rows": [
{
"id": "ingress",
"title": "HTTP request + request authorization",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "1 HTTP request; auth-dependent I/O",
"why": "Authenticate and authorize the resource before delivery. Auth provider/cache costs are application dependent.",
"source": {
"path": "packages/eve/src/channel/channel-address.ts",
"symbol": "createChannelAddress"
}
},
{
"id": "lookup",
"title": "SDK hook lookup",
"modes": ["stable", "alias", "handoff"],
"lane": "critical",
"operations": "1 hooks.getByToken",
"why": "resumeHook(token, command) resolves the live hook and its resume context. No eve preflight; no metadata hydration.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/resume-hook.js",
"symbol": "async function resumeHookImpl"
}
},
{
"id": "missing",
"title": "Try alias before creating",
"modes": ["new"],
"lane": "conditional",
"operations": "0 for ID-only; 1 hooks.getByToken for an unowned alias",
"why": "An ID-only create goes straight to start. A missing channel alias starts a candidate immediately; an ambiguous failure does not.",
"source": {
"path": "packages/eve/src/channel/channel-address.ts",
"symbol": "const existing = await dispatch()"
}
},
{
"id": "key",
"title": "Resume payload encryption",
"modes": ["stable", "alias", "handoff"],
"lane": "conditional",
"operations": "0 with stored public key; key/run reads on SDK fallback",
"why": "Current hooks carry resume context. Sealing to the public key is local; this is distinct from decrypting metadata.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/resume-hook.js",
"symbol": "async function resolveHookEncryptionKey"
}
},
{
"id": "receive",
"title": "Durably accept payload",
"modes": ["stable", "alias", "handoff"],
"lane": "critical",
"operations": "1 hook_received event write",
"why": "Commit the command before publishing its wake. Backend retry/dedup capabilities control transport retries.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/resume-hook.js",
"symbol": "async function resumeHookImpl"
}
},
{
"id": "wake",
"title": "Publish owner wake",
"modes": ["stable", "alias", "handoff"],
"lane": "critical",
"operations": "1 queue publish",
"why": "Targets the current owner on its pinned deployment; acceptance requires the durable write and publish.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/resume-hook.js",
"symbol": "async function resumeHookImpl"
}
},
{
"id": "identity",
"title": "Return stable identity to alias caller",
"modes": ["alias", "handoff"],
"lane": "response",
"operations": "0 hook reads; lazy metadata key access as needed",
"why": "Runs AFTER resume acceptance, concurrent with the awakened workflow. Known session addresses and forwarding-only senders do not access metadata.",
"source": {
"path": "packages/eve/src/execution/session-inbox/resume.ts",
"symbol": "get sessionId()"
}
},
{
"id": "start",
"title": "Start original session workflow",
"modes": ["new"],
"lane": "critical",
"operations": "run_created + queue publish",
"why": "One session workflow, no child turn workflow. SDK start may overlap publication and persistence.",
"source": {
"path": "packages/eve/src/execution/workflow-runtime.ts",
"symbol": "async createSession"
}
},
{
"id": "activation",
"title": "Workflow activation / event history",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "run lifecycle writes + history reads, capability/replay dependent",
"why": "Queue delivery is a compute hop, not an extra producer HTTP call. Retained VM and preload paths differ from cold replay.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/suspension-handler.js",
"symbol": "handleSuspension"
}
},
{
"id": "claims",
"title": "Register stable inbox and initial alias",
"modes": ["new"],
"lane": "critical",
"operations": "1 hook_created per address; one concurrent claim batch",
"why": "One stable address, plus the requested alias. getConflict is a registration fence preventing duplicate first-turn execution, not hooks.getByToken.",
"source": {
"path": "packages/eve/src/execution/session/entry.ts",
"symbol": "const [sessionCreation"
}
},
{
"id": "state",
"title": "Initialize or restore session state",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "new: createSessionStep lifecycle; existing: inline snapshot hydration",
"why": "New-session initialization overlaps address claiming. Current snapshots are carried in durable step results, not fetched from a per-turn snapshot stream.",
"source": {
"path": "packages/eve/src/execution/create-session-step.ts",
"symbol": "async function createSessionStep"
}
},
{
"id": "handoff-check",
"title": "Check idle handoff eligibility",
"modes": ["handoff"],
"lane": "critical",
"operations": "isSessionIdleForHandoffStep lifecycle",
"why": "Only a fresh delivery to an idle session can trigger transfer. Same-deployment and busy sessions do not run this step.",
"source": {
"path": "packages/eve/src/execution/session/handoff.ts",
"symbol": "async checkpoint"
}
},
{
"id": "anchor",
"title": "Register terminal anchor, first handoff only",
"modes": ["handoff"],
"lane": "critical",
"operations": "1 hook_created on original owner's first attempt",
"why": "Keeps the original run and its public stream alive after its execution ownership transfers.",
"source": {
"path": "packages/eve/src/execution/session/entry.ts",
"symbol": "const ensureAnchor"
}
},
{
"id": "release",
"title": "Release owned addresses and drain accepted reads",
"modes": ["handoff"],
"lane": "critical",
"operations": "1 hook_disposed per address",
"why": "If another accepted command is found, reclaim and abandon handoff. Release and claim are not atomic.",
"source": {
"path": "packages/eve/src/execution/session-inbox/inbox.ts",
"symbol": "async release()"
}
},
{
"id": "successor",
"title": "Register activation callback and start successor",
"modes": ["handoff"],
"lane": "critical",
"operations": "activation hook_created + startSessionOwnerStep lifecycle + run_created + publish",
"why": "Activation callback is registered before starting a run that can signal it. Successor receives explicit anchorRunId, snapshot, address set, and configured timeout duration. Successful activation restarts that duration.",
"source": {
"path": "packages/eve/src/execution/session/handoff.ts",
"symbol": "async start"
}
},
{
"id": "reclaim",
"title": "Validate and claim transferred addresses",
"modes": ["handoff"],
"lane": "critical",
"operations": "validation step lifecycle + 1 hook_created per address, batched",
"why": "No model work until all claims succeed. Preserves stable identity and uses the original stream writer.",
"source": {
"path": "packages/eve/src/execution/session/entry.ts",
"symbol": "await validateSessionCheckpointStep"
}
},
{
"id": "ack",
"title": "Acknowledge successor activation",
"modes": ["handoff"],
"lane": "critical",
"operations": "signalSessionOwnerActivationStep + resume lookup/write/publish",
"why": "Old owner can now exit or park as anchor. Later owners signal the anchor only at session end.",
"source": {
"path": "packages/eve/src/execution/session/handoff-steps.ts",
"symbol": "signalSessionOwnerActivationStep"
}
},
{
"id": "timeout",
"title": "Start deadline workflow concurrently",
"modes": ["new", "handoff"],
"lane": "background",
"operations": "startSessionTimeoutStep + timer run_created/publish/lifecycle + durable wait scheduling",
"why": "Default deadline infrastructure. Does not block the first model call; startup operations are joined before the session loop advances.",
"source": {
"path": "packages/eve/src/execution/session/entry.ts",
"symbol": "const initialTurn"
}
},
{
"id": "abort",
"title": "SDK cancellation hook and abort stream",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "1 abrt_* hook_created for the new turn; abort stream read",
"why": "AbortSignal transport is required for cancelling active durable steps. No eve getConflict call and no steering abort.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/serialization.js",
"symbol": "function reduceAbortWithListener"
}
},
{
"id": "step",
"title": "Execute turnStep",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "step_started; step_created/queue delivery when not inline",
"why": "SDK may execute inline or queue a step. Registration awaiters affect inline eligibility; do not equate a step call with exactly one network request.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/suspension-handler.js",
"symbol": "const lazyInlineCorrelationIds"
}
},
{
"id": "prepare",
"title": "Rehydrate context, deliver message, prepare model",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "local work + authored hooks/connections/sandbox I/O",
"why": "No universal count: authored integrations, dynamic model selection, memory, sandbox, and tracing can add work before the provider call.",
"source": {
"path": "packages/eve/src/execution/session/turn-step.ts",
"symbol": "async function turnStep"
}
},
{
"id": "writer",
"title": "Resolve stream writer encryption/routing",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "conditional",
"operations": "run/key reads depending on writable serialization and caches",
"why": "Original owner uses getWritable(); a successor uses the anchor run's forwarded writable. Stream names are run-scoped.",
"source": {
"path": "packages/eve/node_modules/@workflow/core/dist/runtime/run.js",
"symbol": "getWritable(options"
}
},
{
"id": "preamble",
"title": "Publish pre-model events",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "stream write batches; batch count is variable",
"why": "Lifecycle events and authored handlers can be awaited before the model call. Count actual stream batches, not individual events.",
"source": {
"path": "packages/eve/src/execution/session/turn-step.ts",
"symbol": "await emitTurnPreamble"
}
},
{
"id": "model",
"title": "MODEL REQUEST — stop time-to-model clock",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "critical",
"operations": "1 provider request for this first call",
"why": "Provider response latency is outside time-to-model. Subsequent tool/model cycles have their own costs.",
"source": {
"path": "packages/eve/src/execution/session/turn-step.ts",
"symbol": "await runModelCallBatch"
}
},
{
"id": "settle",
"title": "Commit results, admit steering, settle turn",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "completion",
"operations": "step_completed + optional next step + settleTurnStep + stream batches",
"why": "Steering uses the same turn after a committed boundary; queue waits for settlement. No child turn run or owner-release handshake per ordinary turn.",
"source": {
"path": "packages/eve/src/execution/session/turn.ts",
"symbol": "async runTurn"
}
},
{
"id": "read",
"title": "Client stream observer",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "observer",
"operations": "stream GET + read-key resolution as needed; tail-info only when requested",
"why": "Separate clock/branch. An already-open stream is not a new request per chunk. Reconnects target the original run.",
"source": {
"path": "packages/eve/src/execution/workflow-runtime.ts",
"symbol": "async getEventStream"
}
},
{
"id": "activity",
"title": "Optional channel activity collector",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "conditional",
"operations": "new root collector start; hook + activity resume/write/publish batches",
"why": "Only channels with activity renderers. Collector startup can precede session start; separate from the ordinary ID-only path.",
"source": {
"path": "packages/eve/src/execution/workflow-runtime.ts",
"symbol": "let collectorRunId"
}
},
{
"id": "reset",
"title": "Explicit reset release acknowledgement",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "conditional",
"operations": "bounded hooks.getByToken polling after reset acceptance",
"why": "Not an ordinary send cost. Confirms the previous owner released the stable address before reset returns.",
"source": {
"path": "packages/eve/src/execution/workflow-runtime.ts",
"symbol": "async function waitForCommandHookRelease"
}
},
{
"id": "resolve",
"title": "Explicit resolveSession()",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "conditional",
"operations": "1 hooks.getByToken + lazy metadata hydration",
"why": "Requested read-only identity resolution. Never used as a send preflight.",
"source": {
"path": "packages/eve/src/execution/workflow-runtime.ts",
"symbol": "async resolveContinuation"
}
},
{
"id": "task-owner",
"title": "Background task ownership resolution",
"modes": ["new", "stable", "alias", "handoff"],
"lane": "conditional",
"operations": "bounded hooks.getByToken polling inside durable work",
"why": "Not the ordinary turn path. Reads runId only; no metadata hydration.",
"source": {
"path": "packages/eve/src/execution/workflow-runtime.ts",
"symbol": "async function waitForCommandHookOwner"
}
}
]
}