fix(run): --embedder-config is refused, not silently dropped
Walked from a fresh clone: `--embedder-config` was accepted in every mode without `--semantic-retrieval` and then had no effect whatsoever. MEASURED, not inferred — an injected embedder is consulted ZERO times with the flag off and once with it on, because the only consumer is the HybridRanker that flag builds; the default StructuralRetriever takes no embedder at all. That is the silent-ignore this CLI's flag contract exists to prevent, and the same ground on which `--semantic-retrieval` itself is already refused when it cannot take effect. REFUSED, not wired — the opposite call from `--scripted-replies` in portfolio mode, and for a stated reason: there the seam already existed, so refusing would have left a whole mode without an offline door. Here there is nothing to wire to. Mode-independent (both modes gate the embedder on the same flag) and placed ABOVE the scripted door, mirroring the required-args hoist: a refused run must not first print a banner claiming a scripted loop closed. Five mutations against the WHOLE suite, all red, each isolating one seam: detach the refusal (3 red) · scope it to single-project mode (portfolio arm red) · move it below the banner (banner arm red, rc intact) · build the ranker unconditionally (the zero-consultation measurement red) · ignore the injected embedder (its control red). 663 -> 668 tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GyAbxJoyypnLLUDcMvnKh8
This commit is contained in:
parent
f87d555840
commit
a109a703e2
2 changed files with 169 additions and 0 deletions
|
|
@ -1273,6 +1273,33 @@ def main(argv: list[str] | None = None) -> int:
|
|||
)
|
||||
return 1
|
||||
|
||||
# --embedder-config selects the embedder for the HybridRanker, and that ranker is built ONLY
|
||||
# when semantic_retrieval is on; the default StructuralRetriever takes no embedder at all. So
|
||||
# without --semantic-retrieval the config is loaded fail-fast and then dropped on the floor —
|
||||
# MEASURED, not inferred: an injected embedder is consulted ZERO times with the flag off and
|
||||
# once with it on (tests/test_run_cli.py::test_injected_embedder_is_never_consulted_with_the
|
||||
# _flag_off + its control). That is the silent-ignore this CLI's flag contract exists to
|
||||
# prevent, and the same ground on which --semantic-retrieval itself is refused above when it
|
||||
# cannot take effect.
|
||||
#
|
||||
# REFUSED, not wired — the opposite call from --scripted-replies in portfolio mode, and for a
|
||||
# stated reason: there the seam already existed (run_portfolio takes the same client_factory),
|
||||
# so refusing would have left a whole mode without an offline door. Here there is nothing to
|
||||
# wire to; an embedder has no job outside the hybrid ranker.
|
||||
#
|
||||
# MODE-INDEPENDENT (hence above the portfolio dispatch, not inside either branch): both modes
|
||||
# gate the embedder on the same flag, since run_portfolio forwards it to run_project unchanged.
|
||||
# Placed ABOVE the scripted door for the reason the required-args guard was hoisted there — a
|
||||
# refused run must not first print a banner claiming a scripted loop closed.
|
||||
if args.embedder_config is not None and not args.semantic_retrieval:
|
||||
print(
|
||||
"run refused: --embedder-config requires --semantic-retrieval (the embedder is only "
|
||||
"consulted by the hybrid ranker that flag builds — without it the config would be "
|
||||
"loaded and then ignored)",
|
||||
file=sys.stderr,
|
||||
)
|
||||
return 1
|
||||
|
||||
# The scripted door (offline WHOLE-loop run over the caller's own data). Resolved BEFORE the
|
||||
# dry-run branch so the two offline modes cannot both be honoured — and BEFORE the portfolio
|
||||
# dispatch, because the door serves BOTH modes. It originally sat below that dispatch, which
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue