fix(rectification): health distinguish focuses persist again; segment-gain order on by default for windows <= 21 minutes (BUG-1142, BUG-1143)
BUG-1142: distinguish focuses wrote the planner domain verbatim, and health_pressure is not in the focus table's target_domain check. The write failed inside a swallowed retry and the session went straight to delivery although tap cards remained. Every focus write now goes through focusTargetDomain (persistableFocusDomain, BUG-672), and focus-to-probe matching uses sameCollectDomain. BUG-1143: segmentOrderEnabledFor turns segment-gain probe order on by default when the scanned window is at most 21 minutes, where the 77-case persisted replay gained head hits with no lost truth segment. RECTIFICATION_SEGMENT_ORDER =off disables it; =on keeps the 61-minute research envelope. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
04c09cbf4d
commit
564eede340
@@ -62,3 +62,19 @@ export function orderProbesBySegment(input: {
|
||||
return input.probes.map((probe, index) => ({ probe, index, gain: segmentInformationGain(probe, weights, input.segments, input.offsets) }))
|
||||
.sort((a, b) => b.gain - a.gain || a.index - b.index).map((row) => row.probe);
|
||||
}
|
||||
|
||||
/**
|
||||
* Production default for segment-gain probe order (BUG-1143). The 77-case persisted replay
|
||||
* (2026-10-01) gained head hits with no lost truth segment at windows <= 21 minutes; at 61
|
||||
* minutes it lost truth segments, traced to the health-focus write failure (BUG-1142), so the
|
||||
* default stays at 21 until that replay is rerun. "off" disables; "on" keeps the research
|
||||
* envelope used by the persisted replay harness.
|
||||
*/
|
||||
export const SEGMENT_ORDER_DEFAULT_MAX_WINDOW = 21;
|
||||
export const SEGMENT_ORDER_RESEARCH_MAX_WINDOW = 61;
|
||||
|
||||
export function segmentOrderEnabledFor(windowMinutes: number | null | undefined, flag: string | undefined): boolean {
|
||||
if (flag === "off" || !windowMinutes || windowMinutes <= 0) return false;
|
||||
const limit = flag === "on" ? SEGMENT_ORDER_RESEARCH_MAX_WINDOW : SEGMENT_ORDER_DEFAULT_MAX_WINDOW;
|
||||
return windowMinutes <= limit;
|
||||
}
|
||||
|
||||
@@ -821,14 +821,14 @@ function liveDistinguishProbe(
|
||||
isValidDistinguishProbe({ ...probe, role: "distinguish" })
|
||||
&& (schemaKey
|
||||
? probe.semantic_key === schemaKey
|
||||
: (!focus.targetDomain || probe.domain === focus.targetDomain))
|
||||
: (!focus.targetDomain || sameCollectDomain(probe.domain, focus.targetDomain)))
|
||||
);
|
||||
const fromEvents = (eventProbes ?? []).find(matchEvent) ?? null;
|
||||
if (fromEvents) return fromEvents;
|
||||
const matchContrast = (probe: CandidateDiscriminatorProbe) => (
|
||||
schemaKey
|
||||
? probe.semanticKey === schemaKey
|
||||
: (!focus.targetDomain || probe.domain === focus.targetDomain)
|
||||
: (!focus.targetDomain || sameCollectDomain(probe.domain, focus.targetDomain))
|
||||
);
|
||||
const fromContrast = (contrastProbes ?? []).find(matchContrast);
|
||||
if (!fromContrast) return null;
|
||||
@@ -2580,7 +2580,7 @@ export function buildMethodFollowupPlan(input: {
|
||||
: themeFromDomain ?? (focus.intent === "out_of_sample_check" ? "oos_blind" : "education_style")
|
||||
) as MethodFollowup["ask_theme"];
|
||||
const matchingVerify = (input.eventProbes ?? []).find((probe) => (
|
||||
probe.domain === focus.targetDomain
|
||||
sameCollectDomain(probe.domain, focus.targetDomain)
|
||||
|| REVERSE_VERIFY_THEME[probe.domain as keyof typeof REVERSE_VERIFY_THEME] === keepAskTheme
|
||||
));
|
||||
const schema = focus.expectedAnswerSchema;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* write a fresh inference_state, but with an empty answer ledger.
|
||||
*/
|
||||
import { shouldForceMinuteAfterSubBlocks } from "./block-scan.ts";
|
||||
import { segmentOrderEnabledFor } from "../core/segment-probe-order.ts";
|
||||
import { scanCaseSegments } from "./segment-scan.ts";
|
||||
import { targetChartsForDomain } from "../core/segment-summary.ts";
|
||||
import { buildProductCaseInferenceState } from "./product-inference.ts";
|
||||
@@ -450,7 +451,7 @@ export async function scoreAndPersistCurrentEvidence(input: {
|
||||
: undefined;
|
||||
const inference = buildProductCaseInferenceState({
|
||||
segmentMinutes, segmentTargets, segmentScanComplete: Boolean(segmentMinutes),
|
||||
segmentOrderEnabled: process.env.RECTIFICATION_SEGMENT_ORDER === "on",
|
||||
segmentOrderEnabled: segmentOrderEnabledFor(segmentMinutes?.length, process.env.RECTIFICATION_SEGMENT_ORDER),
|
||||
range: candidateRange,
|
||||
candidates: score.candidates,
|
||||
evidence: scorable,
|
||||
|
||||
@@ -272,6 +272,20 @@ export function persistableFocusDomain(domain: string | null | undefined): strin
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The domain a focus row may store. Every intent goes through persistableFocusDomain:
|
||||
* the table only accepts education/career/relationship/relocation/finance/health/family/other,
|
||||
* while planner domains include health_pressure and occupation (BUG-672). A raw
|
||||
* health_pressure on a distinguish focus failed the check constraint, the write was
|
||||
* swallowed and the session ended early (BUG-1142).
|
||||
*/
|
||||
export function focusTargetDomain(followup: Pick<MethodFollowup, "intent" | "domain">): string | null {
|
||||
return persistableFocusDomain(followup.domain)
|
||||
?? (followup.intent === "collect_method_evidence"
|
||||
? persistableFocusDomain(collectQuestionDomain(followup.domain))
|
||||
: null);
|
||||
}
|
||||
|
||||
function clampFocusTargetKind(kind: string | null | undefined): string | null {
|
||||
const value = kind?.trim() || "";
|
||||
if (!value) return null;
|
||||
@@ -672,10 +686,7 @@ async function persistServerOwnedFocusCore(input: {
|
||||
questionId,
|
||||
intent: followup.intent,
|
||||
targetEvidenceId: followup.date_reliability_evidence_id ?? null,
|
||||
targetDomain: followup.intent === "collect_method_evidence"
|
||||
? persistableFocusDomain(followup.domain)
|
||||
?? persistableFocusDomain(collectQuestionDomain(followup.domain))
|
||||
: followup.domain,
|
||||
targetDomain: focusTargetDomain(followup),
|
||||
targetKind: followup.intent === "collect_method_evidence"
|
||||
? collectFocusTargetKind(followup)
|
||||
: null,
|
||||
|
||||
Reference in New Issue
Block a user