Problem
The current storyboard CI runner loads the training agent, SDK compliance runtime, compiled schema graph, embedded HTTP server, and multiple storyboards into one Node.js process. Reset helpers clear known logical stores between storyboards, but they cannot prove that every SDK cache, validator graph, timer, transport, socket, and module-level object has been released.
This allowed latent correctness bugs to turn into runner-wide resource failures:
webhook_emission: no result after ~97 seconds, ~13.7 GB peak RSS (adcp-client#2653).
wholesale_feed_products_scope_isolation: incorrect public/account projection, ~8.3 GB peak RSS (adcp-client#2654).
- Adjacent proposal-finalization cases: committed-state handoff failure, ~17.6 GB combined peak RSS (adcp#6776).
The hosted runner then terminates the shard before it emits totals. Increasing the matrix to 48 fresh hosted jobs and quarantining the pathological storyboards restored CI, but it is expensive containment rather than a durable runner architecture.
Scope
This issue owns runner infrastructure only:
- Execute each storyboard in a fresh child process. The orchestrator MUST NOT load the training agent or SDK schema graph into its own long-lived process.
- Apply a per-storyboard wall-clock limit and a calibrated memory/RSS budget.
- Terminate the complete child process group on timeout, memory breach, or completion.
- Record structured per-storyboard telemetry: elapsed time, peak RSS, exit code/signal, timeout/resource-limit status, and whether a complete result envelope was emitted.
- Aggregate child results without losing successful siblings when one storyboard crashes or is killed.
- Keep the required lane on the standard GitHub-hosted runner. A larger runner MAY be used only for non-required diagnostic heap profiling.
- Once child isolation is proven, reduce the current 48 checkout/install jobs to a smaller fixed matrix (target 4–8 orchestrators), each running assigned storyboards as isolated children.
This issue does not own the underlying behavioral fixes. Those remain in #6776, adcontextprotocol/adcp-client#2653, and adcontextprotocol/adcp-client#2654.
Design constraints
- Do not use worker threads; they share the process and do not provide a clean heap/module boundary.
- Do not depend on graceful SDK/V8 disposal to make progress after a storyboard has emitted its result.
- Resource limits must be calibrated from measured healthy-storyboard baselines rather than arbitrary thresholds.
- Current and released compliance bundles must retain their existing applicability semantics.
- A killed child must produce a precise runner diagnostic instead of a missing-totals ambiguity.
- Logs and telemetry must remain synthetic-test-safe and suitable for CI artifacts.
Acceptance criteria
- A test fixture that intentionally leaks memory or hangs is isolated, killed, and reported without killing the orchestrator or losing sibling results.
- A child that emits a valid result and then hangs during disposal is terminated after its result is durably captured.
- Peak RSS and elapsed time are visible per storyboard in CI artifacts.
- Repeated execution of the full current
/sales set has bounded orchestrator memory.
- The current
/sales required checks pass on the standard hosted runner with a substantially smaller job matrix.
- Existing required-clean, exact-result, and aggregate floor checks remain fail-closed.
- Temporary quarantines are removed only when their owning behavioral issues are fixed; process isolation must not turn a failing storyboard into a passing one.
Follow-up ownership
If profiling identifies retained objects inside @adcp/sdk/testing, open a focused adcp-client issue with heap evidence and an explicit disposal/reset contract. Do not pre-assign unproven retention to the SDK.
Problem
The current storyboard CI runner loads the training agent, SDK compliance runtime, compiled schema graph, embedded HTTP server, and multiple storyboards into one Node.js process. Reset helpers clear known logical stores between storyboards, but they cannot prove that every SDK cache, validator graph, timer, transport, socket, and module-level object has been released.
This allowed latent correctness bugs to turn into runner-wide resource failures:
webhook_emission: no result after ~97 seconds, ~13.7 GB peak RSS (adcp-client#2653).wholesale_feed_products_scope_isolation: incorrect public/account projection, ~8.3 GB peak RSS (adcp-client#2654).The hosted runner then terminates the shard before it emits totals. Increasing the matrix to 48 fresh hosted jobs and quarantining the pathological storyboards restored CI, but it is expensive containment rather than a durable runner architecture.
Scope
This issue owns runner infrastructure only:
This issue does not own the underlying behavioral fixes. Those remain in #6776, adcontextprotocol/adcp-client#2653, and adcontextprotocol/adcp-client#2654.
Design constraints
Acceptance criteria
/salesset has bounded orchestrator memory./salesrequired checks pass on the standard hosted runner with a substantially smaller job matrix.Follow-up ownership
If profiling identifies retained objects inside
@adcp/sdk/testing, open a focused adcp-client issue with heap evidence and an explicit disposal/reset contract. Do not pre-assign unproven retention to the SDK.