Skip to content

Process-isolate storyboard execution and enforce per-storyboard resource budgets #6778

Description

@bokelley

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:

  1. 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.
  2. Apply a per-storyboard wall-clock limit and a calibrated memory/RSS budget.
  3. Terminate the complete child process group on timeout, memory breach, or completion.
  4. Record structured per-storyboard telemetry: elapsed time, peak RSS, exit code/signal, timeout/resource-limit status, and whether a complete result envelope was emitted.
  5. Aggregate child results without losing successful siblings when one storyboard crashes or is killed.
  6. Keep the required lane on the standard GitHub-hosted runner. A larger runner MAY be used only for non-required diagnostic heap profiling.
  7. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingclaude-triagedIssue has been triaged by the Claude Code triage routine. Remove to re-triage.compliance-suitepriority:P1High priority: important bug or follow-up, not immediate P0

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions