Add Stop-B authority: deterministic validator overrides LLM stop
Phase 4 of the two-stop work. The harness already pre-empts the LLM with deterministic stops and guided probes, but an LLM-originated should_stop could still end the loop while the validator saw remaining opportunity. Add harness._stop_authority, exposed as context["stop_authority"], whose `authorized` mirrors the deterministic harness stop decision and whose `opportunity_remains` flags an open topology frontier or a high-value planned candidate. In study tune, an LLM-originated should_stop is now honored only when the validator authorizes it; an unauthorized stop is vetoed (bounded budget) so the loop cannot converge prematurely on the agent's say-so. File- and harness-originated stops are unaffected, and the stop reason chain is recorded. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -226,6 +226,8 @@ def cmd_study_tune(args: argparse.Namespace) -> int:
|
||||
if proposal_files and max_trials > len(proposal_files):
|
||||
max_trials = len(proposal_files)
|
||||
executed: list[dict[str, object]] = []
|
||||
stop_vetoes = 0
|
||||
max_llm_stop_vetoes = 1
|
||||
for idx in range(max_trials):
|
||||
state = store.load_state(study.study_id)
|
||||
if state.tuning_stop_reason:
|
||||
@@ -334,7 +336,34 @@ def cmd_study_tune(args: argparse.Namespace) -> int:
|
||||
proposal = parse_proposal_text(proposal_text, study)
|
||||
store.write_proposal(study.study_id, proposal_name, proposal)
|
||||
if proposal.should_stop:
|
||||
if proposal_name.startswith("harness-stop-"):
|
||||
is_harness_stop = proposal_name.startswith("harness-stop-")
|
||||
is_llm_stop = not is_harness_stop and proposal_source is None
|
||||
stop_authority = (
|
||||
harness_context.get("stop_authority")
|
||||
if isinstance(harness_context, dict)
|
||||
else None
|
||||
)
|
||||
authorized = stop_authority is None or bool(stop_authority.get("authorized"))
|
||||
# Stop-B authority: the deterministic validator overrides an
|
||||
# LLM-originated stop. Veto an unauthorized stop (bounded) so the
|
||||
# loop does not converge prematurely on the agent's say-so alone.
|
||||
if is_llm_stop and not authorized and stop_vetoes < max_llm_stop_vetoes:
|
||||
stop_vetoes += 1
|
||||
executed.append(
|
||||
{
|
||||
"trial_id": None,
|
||||
"proposal_name": proposal_name,
|
||||
"proposal_source": "llm",
|
||||
"stop_vetoed": True,
|
||||
"reason": "validator_did_not_authorize_stop",
|
||||
"validator_reason": (
|
||||
stop_authority.get("reason") if stop_authority else None
|
||||
),
|
||||
"diagnosis": proposal.diagnosis,
|
||||
}
|
||||
)
|
||||
continue
|
||||
if is_harness_stop:
|
||||
proposal_source_label = "harness"
|
||||
else:
|
||||
proposal_source_label = str(proposal_source) if proposal_source else "llm"
|
||||
@@ -344,6 +373,11 @@ def cmd_study_tune(args: argparse.Namespace) -> int:
|
||||
"proposal_name": proposal_name,
|
||||
"proposal_source": proposal_source_label,
|
||||
"stopped": True,
|
||||
"stop_authorized_by": (
|
||||
"validator"
|
||||
if (is_harness_stop or authorized)
|
||||
else "llm_after_veto_budget"
|
||||
),
|
||||
"diagnosis": proposal.diagnosis,
|
||||
"state_best_trial_id": state.best_trial_id,
|
||||
"state_best_request_rate": state.best_request_rate,
|
||||
|
||||
Reference in New Issue
Block a user