Skip to content

fix(runner): cascade-skip downstream stateful steps when phase capability gate unmet - #2802

Merged
bokelley merged 3 commits into
adcontextprotocol:mainfrom
garvitkaushik-123:fix/phase-capability-cascade-7115
Sep 1, 2026
Merged

fix(runner): cascade-skip downstream stateful steps when phase capability gate unmet#2802
bokelley merged 3 commits into
adcontextprotocol:mainfrom
garvitkaushik-123:fix/phase-capability-cascade-7115

Conversation

@garvitkaushik-123

@garvitkaushik-123 garvitkaushik-123 commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Track context outputs from phases skipped by an unmet requires_capability gate and stop dependent steps before dispatch, including non-stateful expect_error steps and explicit context_inputs.
  • Preserve declared topology: depends_on: [], targeted unrelated dependencies, and sibling any_of branches remain independent; ordinary malformed expect_error vectors keep their existing wire behavior.
  • Report capability-caused prerequisite skips as neutral not_applicable outcomes while leaving generic not_applicable, missing_tool, and prerequisite_failed coverage gaps partial.
  • Add a patch changeset and regression coverage for gated/satisfied paths, implicit stateful cascades, dependency scoping, branch peers, no-dispatch behavior, and compliance bundle scoring.

Closes adcontextprotocol/adcp#7115

Test plan

  • npm run build
  • npm run typecheck
  • npm run lint (0 errors)
  • node --test --test-reporter spec test/lib/storyboard-phase-capability-cascade.test.js test/lib/compliance-bundle-results.test.js test/lib/storyboard-cascade-skip-on-skip.test.js test/lib/storyboard-runner-output-contract-v2-runner.test.js (82/82 pass)
  • git diff --check
  • Full library run reached 14,117 passing tests before the sandbox's ephemeral PostgreSQL endpoint disappeared; remaining live-backend tests failed/cancelled with ECONNREFUSED and are left to CI's managed services.

When a phase-level `requires_capability` gate is unmet, the runner skips
the phase but does not register it in `phaseStatefulCascades`. Downstream
phases with stateful steps that reference `$context.*` from the skipped
phase see no cascade trigger and execute with unresolved placeholder
strings on the wire.

Register capability-gated phases that contain stateful steps into
`phaseStatefulCascades` with reason `not_applicable` so downstream
`cascadeForPhase()` checks correctly trip `prerequisite_failed`.

Closes adcontextprotocol/adcp#7115
@garvitkaushik-123
garvitkaushik-123 force-pushed the fix/phase-capability-cascade-7115 branch from c2dd243 to 896a0fb Compare September 1, 2026 05:07
aao-secretariat[bot]
aao-secretariat Bot previously approved these changes Sep 1, 2026

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve — well-scoped runner bugfix (adcp#7115).

Capability-gated phases now cascade-skip dependent steps before dispatch instead of sending unresolved $context placeholders on the wire, and report as neutral not_applicable in bundle scoring. Reviewer verified no pass-count inflation, correct scoping to capability gates only, preserved any_of/depends_on topology, and no regression to intentional expect_error malformed-vector behavior. Changeset (.changeset/calm-runners-skip-capabilities.md) is present alongside the src/lib/** changes, and new behavior is covered by test/lib/storyboard-phase-capability-cascade.test.js.

No Critical/High/Medium findings. Not gated (gated_paths: false), not high-risk, no author-team gate. Falls through to row 9.

@aao-secretariat aao-secretariat Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ladon verdict: Approve

Approve.

Clean pass with no findings. The delta since the prior approve is a single logical change: an added description on the collection field in the synced upstream schemas/registry/registry.yaml, with src/lib/registry/types.generated.ts regenerated to mirror it verbatim. Documentation/metadata only — no code behavior, wire-shape, or witness-fidelity change. Generated file matches source; no changeset needed since the change is generated/metadata-only.

Decision-table walkthrough:

  • Rows 1: no critical/high findings.
  • Row 2: gated_paths is false — not triggered (review_decision is REVIEW_REQUIRED, but the deterministic gate does not apply).
  • Row 3: high_risk is true but the reason is (modified), not (deleted).
  • Row 4: no medium findings.
  • Row 5: high_risk (modified) present, but no medium finding — not triggered.
  • Row 6: prior decision was approve, not escalate.
  • Row 7: no no-auto-approve team match.
  • Row 8: fewer than three medium findings (zero).
  • Row 9: approve.

The high-risk flag fires only because schemas/registry/registry.yaml matches schemas/registry/** as a modification; with no medium-or-higher finding on that file, the modification is presumed safe per the flag-reading guidance.

@bokelley
bokelley merged commit d68168b into adcontextprotocol:main Sep 1, 2026
54 of 57 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants