fix(host-mode): state the shipped Turn host default in the plan contract - #4476
Conversation
The host-mode planner previews the resolved default instead of pinning a host, and three surfaces justified that preview with semantics the governed Turn does not ship: the planner comment, the `host` field in `docs/reference/protocols/host-mode-plan-v0.md`, and the smoke comment all said the headless default is resolved from the operator credential. `control_plane.turn_driver.host_binding.selected_turn_host` is environment-independent. It ships one explicit product default that `LOOPX_TURN_HOST` or an explicit `--host` re-points, and a configured credential authenticates that host instead of selecting it. The preview behavior is already right; only its stated reason was wrong, and that is the sentence a later editor would act on, so it now names the owner that decides the default instead of restating a rule that no longer holds. The smoke pins the reason too: the headless mapping is built with and without `DEEPSEEK_API_KEY` and must stay identical and unpinned, so wiring credential resolution back into the planner fails a public check rather than passing review. Validation: `examples/host-mode-plan-smoke.py`, `examples/project/host-mode-plan-cli-smoke.py`, `tests/test_host_mode_planner.py` (2 passed), `tests/test_host_parity_smoke.py` (38 passed), and `scripts/generate_semantic_inventory.py --check` (up to date). Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Self-review validation commentChanged surfaces: Checks run, all at head Failures/skips: none. Manual holds: none. Why this coverage is enough: the only executable change is a comment inside the planner, so behavior is unchanged by construction; the contract prose has no other consumer than the smoke's doc-wiring check, which passes; and the new assertion is the regression guard for the sentence being fixed (the headless mapping must not depend on |
What changed
The host-mode planner previews the resolved host default for the headless Turn modes instead of pinning one, which is the right behavior. Three surfaces explained that preview with semantics the governed Turn does not ship:
RESOLVED_DEFAULT_TURN_HOST_MODEScomment inloopx/host_mode_planner.py;hostfield description indocs/reference/protocols/host-mode-plan-v0.md;examples/host-mode-plan-smoke.py.All three said the headless default is resolved from the operator credential.
control_plane.turn_driver.host_binding.selected_turn_host()is environment-independent: it ships one explicit product default thatLOOPX_TURN_HOSTor an explicit--hostre-points, and a configured credential authenticates that host instead of selecting it. The preview behavior is unchanged; only the stated reason was wrong — and a stated reason is what a later editor acts on, so the comment now names the owner that decides the default instead of restating a rule that does not hold.The smoke pins the reason as well: the headless mapping is built with and without
DEEPSEEK_API_KEYand must stay identical and unpinned. Wiring credential resolution back into the planner now fails a public check instead of passing review.Scope
Public-safe: no private context, credentials, host names, or local paths. No runtime behavior change, no new CLI surface, no permission or evidence-policy change.
Validation
python3 examples/host-mode-plan-smoke.py→host-mode-planner-smoke ok(includes the new credential-independence check)python3 examples/project/host-mode-plan-cli-smoke.py→ okpython3 -m pytest -q tests/test_host_mode_planner.py→ 2 passedpython3 -m pytest -q tests/test_host_parity_smoke.py→ 38 passedpython3 scripts/generate_semantic_inventory.py --check→ up to dateContext
The credential-resolved Turn default this wording came from was proposed in #4454 and deliberately not adopted: that PR is closed, and
selected_turn_hostkeeps selection independent of the environment.