Skip to content

test(e2e): add runtime tool-guardrail tests (Suite8cToolGuardrailsRun…#139

Open
kowser-orkes wants to merge 1 commit into
mainfrom
feat/tool-guardrail-e2e
Open

test(e2e): add runtime tool-guardrail tests (Suite8cToolGuardrailsRun…#139
kowser-orkes wants to merge 1 commit into
mainfrom
feat/tool-guardrail-e2e

Conversation

@kowser-orkes

Copy link
Copy Markdown
Contributor

test(e2e): runtime coverage for tool guardrails + bump server pin to rc.15

Pull Request type

  • Bugfix
  • Feature
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • WHOSUSING.md
  • Other (please describe): e2e test coverage

NOTE: Please remember to run ./gradlew spotlessApply to fix any format violations.

Changes in this PR

Describe the new behavior from this PR, and why it's needed

  • Adds Suite8cToolGuardrailsRuntime (5 tests) — the first e2e coverage that actually executes a
    tool-level guardrail. Every prior test either drove an agent-level guardrail or only inspected
    compiled workflow JSON for a tool-level one, so the worker-registration bug (already fixed on
    main, no client ever polled the guardrail task) shipped completely undetected
  • Tests 1–2: an always-failing RAISE guardrail blocks the run, an always-passing one lets it
    complete — proves the tool-guardrail worker is registered and actually polled, not just present
  • Test 3: agent-level onFail=FIX regression guard, deliberately ungated (passes today) — protects
    against a naive server-side escalation fix discarding a valid fixed_output
  • Tests 4–5 (custom + regex paths): tool onFail=RETRY guardrail must escalate to FAILED/TERMINATED
    once maxRetries is exceeded instead of retrying forever
  • Bumps CONDUCTOR_SERVER_VERSION in agent-e2e.yml: 3.32.0-rc.83.32.0-rc.15, the first
    release carrying the server-side retry-escalation fix — tests 4–5 now run for real instead of skipping
  • Drops the ServerCapabilities version-gate helper (and its unit test) added while the fix was
    unreleased — now that the pin always points at a fixed server, the gate would just be dead code
Before After
Tool-guardrail runtime coverage none — only compiled-JSON assertions existed 5 live e2e tests: raise/pass/fix/escalate against a real agent + tool
Tool onFail=RETRY, maxRetries exceeded untested — server hardcoded the iteration counter, so escalation never fired and the run COMPLETED asserted FAILED/TERMINATED, run for real against the pinned server
CI server pin 3.32.0-rc.8 (predates the fix) 3.32.0-rc.15 (first release with the fix)

Issue #

Alternatives considered

Describe alternative implementation you have considered

  • Keep the escalation tests gated behind ServerCapabilities — dropped; it was only a bridge until
    the pin moved past the fix, and keeping it after would be dead code no run ever exercises
  • Mock the guardrail worker instead of running a real agent + tool — rejected, the point is proving
    the worker is genuinely registered and polled by the server, which a mock can't demonstrate

@codecov

codecov Bot commented Jul 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
see 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kowser-orkes
kowser-orkes marked this pull request as ready for review July 21, 2026 21:17
…time)

Every prior guardrail e2e test either drives an agent-level guardrail or
only inspects compiled workflow JSON for a tool-level one — nothing ever
executed a tool-level guardrail. That gap is exactly how the worker-
registration bug fixed by 55c74dd shipped undetected.

Adds two counterfactual runtime tests against a real echo tool:
- test_tool_raise_guardrail_blocks_run: an always-failing RAISE guardrail
  must fail/terminate the run.
- test_tool_pass_guardrail_lets_run_complete: an always-passing guardrail
  must let the run complete, proving the worker is polled and not simply
  blocking unconditionally.

- test_agent_fix_guardrail_substitutes_output: agent-level FIX guardrail
  substitutes its corrected output. Deliberately UNGATED — verified live
  that it already passes against today's server. It exists to catch a
  regression an escalate() helper to the custom-guardrail normalizer that coerces
  fix->raise unconditionally, without checking whether a fixed_output is
  present — unlike the SDK's own worker handler, which only coerces when
  fixedOutput == null. Applied as-is, that commit would break exactly this
  case.

- test_tool_retry_guardrail_escalates_to_failure /
  test_regex_tool_guardrail_escalates_to_failure: gated behind
  ServerCapabilities.assumeGuardrailEscalationFix() (skip, not @disabled,
  until CONDUCTOR_SERVER_VERSION reaches a fixed release). Verified live
  with the gate forced open (GUARDRAIL_ESCALATION_FIXED=true) against
  today's real, unfixed server: both fail fast (~20-50s) with "Got status:
  COMPLETED" instead of FAILED/TERMINATED — via the
  SDK-worker and server-script paths respectively, confirming they'll
  correctly detect the fix once it ships.
@kowser-orkes
kowser-orkes force-pushed the feat/tool-guardrail-e2e branch from 209ad42 to c30d80e Compare July 21, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant