Skip to content

--web-bg blocks workflows with human_gate even though the dashboard fully supports gate resolution — extend the #198 policy to human gates #286

Description

@decherneyge

conductor run --web-bg aborts at launch when the workflow contains a human_gate (unless --skip-gates), yet the web dashboard has complete gate support: the gate modal, WebSocket gate_response, POST /api/gate-respond, and the conductor gate-respond CLI (#234). Background runs are the mode where web-based gate resolution is most valuable — the guard forces users to choose between the dashboard and gates.

Root cause

The guard (cli/app.py::_abort_web_bg_if_human_gate) papers over a gap in the engine: _handle_gate_with_web (engine/workflow.py) races the terminal prompt against the dashboard unconditionally. With the bg child's stdin=DEVNULL, Prompt.ask raises EOFError instantly, race-wins, cancels the web arm, and crashes the workflow before a dashboard user could respond. Verified by reproducing the race with stdin at /dev/null:

winner: cli_arm
raised: EOFError: EOF when reading a line

Precedent

This is the same failure #198 described for the max-iterations gate, fixed in #202 by _resolve_max_iterations_gate's tiered policy (dashboard + bg/non-TTY → web-only wait, CLI arm deliberately skipped; also racing wait_for_stop() so /api/stop can end the wait). The human-gate path never got that tier — cli_usable = not self._bg_mode and sys.stdin.isatty() already exists one function away.

Proposal

  1. Apply the fix(engine,web): resolve max-iterations gate from dashboard in --web-bg #202 policy to _handle_gate_with_web: when a dashboard is attached and cli_usable is false, wait on the web arm only (racing wait_for_stop()); keep the CLI/web race for foreground TTY.
  2. Retire _abort_web_bg_if_human_gate, or downgrade it to a launch-time notice pointing at the dashboard URL and conductor gate-respond.
  3. Update the --web-bg/human_gate sections in docs/cli-reference.md and the skill references.

Happy to submit a PR for this if the approach sounds right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions