Skip to content

Steer-control eval errors: engine (non-blocking) and integrations/_core.py (raise on any error) disagree #261

Description

@josjeon

Summary

The engine and the SDK integration helper disagree on whether a steer-control evaluation error blocks execution. The engine treats it as non-blocking; the integrations/_core.py helper raises on any error. So whether a steered step is blocked when its evaluator errors/times out depends on which enforcement path the caller uses.

Evidence

Engine — steer errors are explicitly non-blocking; only deny errors fail closed:

engine/src/agent_control_engine/core.py

787   if deny_errored:
788       is_safe = False
790   # Log steer errors for observability (non-blocking)
791   if steer_errored:
797       logger.warning(f"Steer control evaluation failed (non-blocking): ...")

Both deny and steer errors are appended to the returned errors list, but only deny_errored sets is_safe = False. A steer error leaves is_safe unchanged.

SDK integration helper — raises on any non-empty errors:

sdks/python/src/agent_control/integrations/_core.py

73   if result.errors:
77       raise RuntimeError(
78           "Control evaluation failed; execution blocked for safety. ..."

Impact

  • A caller using the framework integration path (_core.py _evaluate_and_enforce, i.e. the ADK/Strands plugins and @control) blocks on a steer-control error.
  • A caller invoking evaluate_controls() directly gets is_safe=True (with the steer error present in result.errors) and does not block unless it inspects errors itself.

Same evaluator error, opposite enforcement outcome, depending on entry point. Easy to hit when a steer control's evaluator times out (e.g. a server-side scorer that is slow or unreachable).

Ask

Decide the intended semantics for a steer-control error (as opposed to a steer match) and make the engine and the integration helper agree:

  • If steer errors should be non-blocking, _core.py should not raise on steer-only errors (filter by action, or key off is_safe).
  • If they should block, the engine should set is_safe = False on steer_errored too.

Either way, document the chosen behavior. Found while writing runtime-behavior docs and verified against the current source paths above.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions