fix(rectification): enforce persisted convergence budgets
This commit is contained in:
@@ -27,6 +27,9 @@ export type DecideNextActionInput = Readonly<{
|
||||
holdoutValidation?: HoldoutValidationStatus;
|
||||
accepted?: boolean;
|
||||
inferenceCredibleRange?: readonly [string, string] | null;
|
||||
inferenceRounds?: number;
|
||||
effectiveAnswerCount?: number;
|
||||
plateauRounds?: number;
|
||||
}>;
|
||||
|
||||
export type RectificationNextAction = Readonly<{
|
||||
@@ -55,6 +58,9 @@ export function decideNextAction(input: DecideNextActionInput): RectificationNex
|
||||
inferenceCredibleRange: input.inferenceCredibleRange,
|
||||
engineAcceptAllowed: input.selectionAllowed,
|
||||
engineProposeAllowed: input.proposeAllowed,
|
||||
inferenceRounds: input.inferenceRounds,
|
||||
effectiveAnswerCount: input.effectiveAnswerCount,
|
||||
plateauRounds: input.plateauRounds,
|
||||
});
|
||||
return { type: decision.nextAction, separation: decision.separation, probe: decision.probe };
|
||||
}
|
||||
|
||||
@@ -14,7 +14,13 @@ import {
|
||||
} from "./candidate-separation.ts";
|
||||
import { rangeFromTimes } from "./credible-range.ts";
|
||||
import type { DroppedProbe } from "../v9/probe-question-contract.ts";
|
||||
import type { RectificationPhase, ResultStatus } from "./types.ts";
|
||||
import { EFFECTIVE_ANSWER_SAFETY_CAP } from "../../birth-time-dynamic-stop-policy.ts";
|
||||
import { RECTIFICATION_POLICY } from "../../rectification-policy.ts";
|
||||
import {
|
||||
DEFAULT_MAX_DISCRIMINATION_ROUNDS,
|
||||
type RectificationPhase,
|
||||
type ResultStatus,
|
||||
} from "./types.ts";
|
||||
|
||||
export type RectificationNextActionType =
|
||||
| "ask_fact_collection"
|
||||
@@ -81,6 +87,10 @@ export type DecideRectificationInput = Readonly<{
|
||||
engineAcceptAllowed?: boolean;
|
||||
engineProposeAllowed?: boolean;
|
||||
datedMethodCollectOpen?: boolean;
|
||||
/** Server-persisted inference counters; never infer these from chat text. */
|
||||
inferenceRounds?: number;
|
||||
effectiveAnswerCount?: number;
|
||||
plateauRounds?: number;
|
||||
}>;
|
||||
|
||||
export function decideRectification(input: DecideRectificationInput): RectificationDecision {
|
||||
@@ -136,7 +146,13 @@ export function decideRectification(input: DecideRectificationInput): Rectificat
|
||||
}
|
||||
if (input.snapshotCurrent === false) {
|
||||
if (probe && !userStopped && input.trainingGateOpen !== false) {
|
||||
return discriminate(separation, holdout, range, probe);
|
||||
return discriminateOrExhaust(
|
||||
input,
|
||||
separation,
|
||||
holdout,
|
||||
range,
|
||||
probe,
|
||||
);
|
||||
}
|
||||
if (!(userStopped && input.candidateScores.length > 0)) {
|
||||
return collect(separation, holdout, range, probe);
|
||||
@@ -144,7 +160,7 @@ export function decideRectification(input: DecideRectificationInput): Rectificat
|
||||
}
|
||||
if (!separation.sufficient) {
|
||||
if (probe && !userStopped) {
|
||||
return discriminate(separation, holdout, range, probe);
|
||||
return discriminateOrExhaust(input, separation, holdout, range, probe);
|
||||
}
|
||||
return completeWithRange(separation, holdout, range, userStopped ? "user_stopped" : "offer");
|
||||
}
|
||||
@@ -153,7 +169,7 @@ export function decideRectification(input: DecideRectificationInput): Rectificat
|
||||
}
|
||||
if (holdout === "failed") {
|
||||
if (probe && !userStopped) {
|
||||
return discriminate(separation, holdout, range, probe);
|
||||
return discriminateOrExhaust(input, separation, holdout, range, probe);
|
||||
}
|
||||
return completeWithRange(separation, holdout, range, "exhausted");
|
||||
}
|
||||
@@ -183,6 +199,25 @@ export function decideRectification(input: DecideRectificationInput): Rectificat
|
||||
});
|
||||
}
|
||||
|
||||
function budgetExhausted(input: DecideRectificationInput): boolean {
|
||||
return (input.inferenceRounds ?? 0) >= DEFAULT_MAX_DISCRIMINATION_ROUNDS
|
||||
|| (input.effectiveAnswerCount ?? 0) >= EFFECTIVE_ANSWER_SAFETY_CAP
|
||||
|| (input.plateauRounds ?? 0) >= RECTIFICATION_POLICY.maxPlateauRounds;
|
||||
}
|
||||
|
||||
function discriminateOrExhaust(
|
||||
input: DecideRectificationInput,
|
||||
separation: CandidateSeparation,
|
||||
holdout: HoldoutValidationStatus,
|
||||
range: readonly [string, string] | null,
|
||||
probe: CandidateDiscriminatorProbe,
|
||||
): RectificationDecision {
|
||||
if (budgetExhausted(input)) {
|
||||
return completeWithRange(separation, holdout, range, "exhausted");
|
||||
}
|
||||
return discriminate(separation, holdout, range, probe);
|
||||
}
|
||||
|
||||
function collect(
|
||||
separation: CandidateSeparation,
|
||||
holdout: HoldoutValidationStatus,
|
||||
|
||||
Reference in New Issue
Block a user