fix(rectification): bind quality cards to the followup probe
Independent Staging Quality Gate / validate (push) Successful in 23m15s
Independent Staging Quality Gate / publish (push) Failing after 36s

Graduation no longer gets the college-experience question, and identical D24 splits only ask once.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-09-04 23:47:51 +08:00
co-authored by Cursor
parent 73c2a1a51e
commit 40c623edf6
9 changed files with 462 additions and 9 deletions
@@ -100,6 +100,7 @@ export type ChoiceCardFollowup = Readonly<{
choice_kind?: EventProbeChoiceKind;
style_options?: readonly EventProbeStyleOption[];
semantic_key?: string;
probe_id?: string;
}>;
export type ChoiceCardEvidence = Readonly<{
@@ -230,12 +231,28 @@ function followupDomain(followup: ChoiceCardFollowup): string | null {
return THEME_DOMAIN[followup.ask_theme] ?? null;
}
function probeMatchesId(item: DiscriminatingEventProbe, probeId: string): boolean {
return item.semantic_key === probeId;
}
function pickProbe(
probes: readonly DiscriminatingEventProbe[] | undefined,
domain: string | null,
followup?: ChoiceCardFollowup,
): DiscriminatingEventProbe | null {
if (!probes?.length) return null;
const probeId = followup?.probe_id?.trim() ?? "";
const semanticKey = followup?.semantic_key?.trim() ?? "";
const hasKey = Boolean(probeId || semanticKey);
if (probeId) {
const byId = probes.find((item) => probeMatchesId(item, probeId));
if (byId) return byId;
}
if (semanticKey) {
const keyed = probes.find((item) => item.semantic_key === semanticKey);
if (keyed) return keyed;
}
if (hasKey) return null;
const inDomain = domain ? probes.filter((item) => item.domain === domain) : [...probes];
const pool = inDomain.length > 0 ? inDomain : probes;
if (followup?.choice_kind === "event_quality") {
@@ -244,10 +261,6 @@ function pickProbe(
);
if (quality) return quality;
}
if (followup?.semantic_key) {
const keyed = pool.find((item) => item.semantic_key === followup.semantic_key);
if (keyed) return keyed;
}
return pool[0] ?? probes[0] ?? null;
}
@@ -386,8 +399,10 @@ export function buildChoiceFrame(
const skipQuestion = skipThisProbe
|| followup.intent === "out_of_sample_check"
|| followup.source === "oos_blind";
const probeKey = followup.semantic_key?.trim() || followup.probe_id?.trim() || "";
const questionBase = `${followup.method_id}:${followup.ask_theme}:${scoring ? "score" : "holdout"}`;
return {
question_id: `${followup.method_id}:${followup.ask_theme}:${scoring ? "score" : "holdout"}`,
question_id: probeKey ? `${questionBase}:${probeKey}` : questionBase,
method_id: followup.method_id,
period: periodFor(input.evidence, domain, input.probes, input.birthDate, followup),
prompt: hypothesis.prompt,
@@ -1666,3 +1666,130 @@ test("GET does not mint a tap card from an out-of-sample spoken collect focus",
});
assert.equal(card, null);
});
const EDUCATION_QUALITY_OPTIONS = [
{ label: "发挥明显失常", answer_class: "yes" },
{ label: "只是将就调剂", answer_class: "weak_yes" },
{ label: "基本如愿录取", answer_class: "no" },
{ label: "当时说不清楚", answer_class: "unsure" },
] as const;
const QUALITY_SPLIT_OUTCOMES = [
{ answer_class: "yes", supports: ["05:00", "05:01"], conflicts: ["05:10", "05:11"] },
{ answer_class: "weak_yes", supports: ["05:00", "05:01"], conflicts: ["05:10", "05:11"] },
{ answer_class: "no", supports: ["05:10", "05:11"], conflicts: ["05:00", "05:01"] },
{ answer_class: "unsure", supports: [], conflicts: [] },
] as const;
function educationQualityProbe(input: {
semanticKey: string;
evidenceId: string;
year: number;
month: number;
meaning: string;
dateLabel: string;
}): DiscriminatingEventProbe {
return {
year: input.year,
month: input.month,
year_label: `${input.year}${input.month} 月前后`,
domain: "education",
event_family: "学业或考试发挥失常、压力特别大",
source: "known_event_quality",
tracks: ["vimshottari", "narayana"],
tracks_agree: true,
unique_minute_claim: false,
user_meaning: input.meaning,
role: "distinguish",
phase: "candidate_discriminator",
information_gain: 0.5,
semantic_key: input.semanticKey,
candidate_split_hash: `${input.semanticKey}:split`,
target_evidence_id: input.evidenceId,
display_date_label: input.dateLabel,
choice_kind: "event_quality",
style_options: EDUCATION_QUALITY_OPTIONS,
expected_outcomes: QUALITY_SPLIT_OUTCOMES,
candidate_ids: ["05:00", "05:01", "05:10", "05:11"],
};
}
test("event_quality cards bind to the followup probe, not the first same-kind probe", () => {
const startProbe = educationQualityProbe({
semanticKey: "education.2014.known_event_quality",
evidenceId: "11111111-1111-4111-8111-111111111111",
year: 2014,
month: 9,
dateLabel: "2014 年 9 月",
meaning: "2014 年 9 月那次上大学,更接近如愿、将就调剂、发挥失常还是说不清。只问那次经历的实际体验,不得改时间范围。",
});
const laterProbe = educationQualityProbe({
semanticKey: "education.2018.known_event_quality",
evidenceId: "22222222-2222-4222-8222-222222222222",
year: 2018,
month: 6,
dateLabel: "2018 年 6 月",
meaning: "2018 年 6 月那次上大学,更接近如愿、将就调剂、发挥失常还是说不清。只问那次经历的实际体验,不得改时间范围。",
});
const probes = [startProbe, laterProbe];
const laterFrame = buildChoiceFrame({
method_id: "d5_education",
ask_theme: "education_style",
domain: "education",
user_prompt_hint: "unused",
intent: "distinguish_candidates",
choice_kind: "event_quality",
semantic_key: laterProbe.semantic_key,
probe_id: laterProbe.semantic_key,
style_options: EDUCATION_QUALITY_OPTIONS,
}, { probes });
assert.ok(laterFrame);
assert.match(laterFrame.question_id, /education\.2018\.known_event_quality/);
assert.doesNotMatch(laterFrame.question_id, /education\.2014\.known_event_quality/);
assert.match(laterFrame.period, /2018 年 6 月/);
assert.doesNotMatch(laterFrame.period, /2014/);
assert.match(laterFrame.prompt, /2018 年 6 月那次上大学/);
assert.doesNotMatch(laterFrame.prompt, /2014/);
assert.match(laterFrame.why, /2018 年 6 月那次上大学/);
assert.doesNotMatch(laterFrame.why, /2014/);
const startFrame = buildChoiceFrame({
method_id: "d5_education",
ask_theme: "education_style",
domain: "education",
user_prompt_hint: "unused",
intent: "distinguish_candidates",
choice_kind: "event_quality",
semantic_key: startProbe.semantic_key,
probe_id: startProbe.semantic_key,
style_options: EDUCATION_QUALITY_OPTIONS,
}, { probes });
assert.ok(startFrame);
assert.match(startFrame.question_id, /education\.2014\.known_event_quality/);
assert.match(startFrame.period, /2014 年 9 月/);
assert.match(startFrame.prompt, /2014 年 9 月那次上大学/);
assert.match(startFrame.why, /2014 年 9 月那次上大学/);
assert.doesNotMatch(startFrame.prompt, /2018/);
});
test("event_quality followup with a missing probe key does not fall back to another quality probe", () => {
const startProbe = educationQualityProbe({
semanticKey: "education.2014.known_event_quality",
evidenceId: "11111111-1111-4111-8111-111111111111",
year: 2014,
month: 9,
dateLabel: "2014 年 9 月",
meaning: "2014 年 9 月那次上大学,更接近如愿、将就调剂、发挥失常还是说不清。只问那次经历的实际体验,不得改时间范围。",
});
const frame = buildChoiceFrame({
method_id: "d5_education",
ask_theme: "education_style",
domain: "education",
user_prompt_hint: "unused",
choice_kind: "event_quality",
semantic_key: "education.2018.known_event_quality",
probe_id: "education.2018.known_event_quality",
style_options: EDUCATION_QUALITY_OPTIONS,
}, { probes: [startProbe] });
assert.equal(frame, null);
});