Skip to content

feat(turn): qualify the credential-resolved default managed flow - #4427

Closed
huangruiteng wants to merge 2 commits into
codex/steward-execution-chip-20260915from
codex/managed-default-turn-slice-20260915
Closed

huangruiteng wants to merge 2 commits into
codex/steward-execution-chip-20260915from
codex/managed-default-turn-slice-20260915

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

What this adds

The credential-resolved default managed flow was shipped across the stack but only the explicit-host path was ever qualified end to end. This PR closes that gap and fixes the one readback claim that flow exposes.

1. operator_credential_bound in the managed executor readback (loopx/control_plane/turn_driver/host_binding.py)

managed_executor_binding("dsh") reported executor_kind: managed even with no operator credential configured. That is the field an operator and the manager header read to know where a Turn's model work is billed and bounded, so it must not be inferred from the host id alone. The binding now also states the narrower claim:

selection executor_kind operator_credential_bound
credential configured, default host managed true
explicit --host dsh, no credential, no runner managed false
explicit --runner, no credential managed true
codex-cli / claude-code / generic-cli individual / generic false

Launch decisions are unchanged: available still decides the fail-closed refusal, and no host moves on its own.

2. Public smoke for the default flow (examples/loopx-turn-managed-default-flow-smoke.py)

Hermetic (local mock OpenAI-compatible SSE endpoint; no operator key, no individual CLI subscription) and driven only through the public CLI:

  • no credential: default host codex-cli, executor individual;
  • credential: default host dsh, executor managed, available: true, mode isolated-headless;
  • credential: turn run-once without --host starts the real dsh runtime, commits one validated Turn (status: committed, result_kind: validated_progress, independent validation passed, one quota slot), and reports mode/executor/status;
  • credential but runtime hidden: typed dsh_runtime_unavailable refusal with no host invocation, no state write, no journal, no spend;
  • explicit --host dsh with no credential: readback reports operator_credential_bound: false.

Validation

  • pytest -q tests/test_loopx_turn_executor.py tests/test_turn_managed_executor_binding.py tests/test_turn_default_host_binding.py → 84 passed
  • examples/loopx-turn-managed-default-flow-smoke.py → passed
  • examples/loopx-turn-managed-executor-binding-smoke.py → passed
  • examples/loopx-turn-dsh-real-e2e-smoke.py --host dsh and --host generic-cli → passed
  • examples/docs-governance-smoke.py → ok
  • tests/test_turn_managed_executor_binding.py tests/test_turn_default_host_binding.py → 27 passed

All runs used the shared repo venv with PYTHONPATH pointed at this worktree; no provider call, no Codex subscription use.

Delivery boundary

Partial by design: the minimal managed slice still owes the second-executor guard (a Turn must fail closed when another executor is already live on the same agent lane). No such guard exists today — the Turn CLI has no lane lease or writer fence, and the Turn session binding carries only goal_id/agent_id/todo_id. That is tracked as a successor item with the evidence rather than guessed at here, so this PR stays reviewable and reversible.

Stack

Stacked on codex/steward-execution-chip-20260915 (#4419). Merge order stays #4420 → #4409 → #4416 → #4417 → #4419 → this PR; #4400 stays standalone.

🤖 Generated with Codex

@huangruiteng
huangruiteng force-pushed the codex/steward-execution-chip-20260915 branch from 2da0bfb to d69970d Compare September 15, 2026 06:48
Codex Product Agent added 2 commits September 15, 2026 14:49
The managed readback reported `executor_kind: managed` for any selected
`dsh` host, even when no operator credential and no runner hook were
configured. That claim is what an operator or frontend reads to decide where a
Turn's model work is billed, so it must not be inferred from the host id alone.

Add `operator_credential_bound` to the managed executor binding: true only when
the operator credential or an explicit runner hook is configured, false for an
explicitly selected dsh host that would fall back to whatever the dsh home
configures, and false for individual and generic executors. Launch decisions are
unchanged; the readback now states the boundary instead of claiming one.

Signed-off-by: Codex Product Agent <codex@loopx.local>
The shipped operator rule resolves the default Turn host from the configured
credential, but the end-to-end qualification only ran an explicit --host. That
left the flow an operator actually uses unqualified: nothing proved that the
default command starts the managed Turn or what it reports while doing so.

Add a hermetic public smoke that drives the default flow through the CLI: no
credential keeps codex-cli/individual, a credential resolves dsh/managed, the
default run-once starts the real dsh runtime against a local mock model endpoint
and commits one validated Turn with mode/executor/status readback, an explicit
dsh host without a credential reports operator_credential_bound=false, and an
unavailable managed runtime fails closed with the typed reason, no host
invocation, no state write, and no quota spend. Document the default flow and the
boundary in the connector reference.

Signed-off-by: Codex Product Agent <codex@loopx.local>
@huangruiteng
huangruiteng force-pushed the codex/managed-default-turn-slice-20260915 branch from 21fbc14 to 5a09c24 Compare September 15, 2026 06:49
@huangruiteng

Copy link
Copy Markdown
Collaborator Author

Superseded by #4443 (feat(turn): select the managed Turn host explicitly).

The value here is kept, and the qualification is stronger: examples/loopx-turn-managed-default-flow-smoke.py still runs the real dsh runtime against a local mock OpenAI-compatible SSE endpoint (no operator key, no individual subscription) and commits one validated Turn. It now qualifies the selected managed default instead of a credential-resolved one.

#4443 also carries the second-executor protection question this PR flagged as open, so the flow evidence and the rule it qualifies land together. Closing to compress the delivery chain.

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