fix(web): offer representative time after occupation notes cover

Dateless occupation_note stayed draft, so classic coverage never finished
and offer-candidates stayed blocked. Confirm those notes, stop crowding
dasha probes with encoded exam quality, and adopt once blocking methods
are covered.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-23 17:21:49 +08:00
parent 6b225a288c
commit 75dbab08b9
11 changed files with 774 additions and 28 deletions
@@ -291,6 +291,20 @@ test("adopt_representative defers method follow-up instead of asking this turn",
assert.equal(plan.session_outcome, "adopt_representative");
});
test("adopt_representative ignores leftover distinguish focus", () => {
const plan = buildMethodFollowupPlan({
evidence: CLASSIC_COVERAGE.filter((item) => item.domain !== "horary"),
sessionOutcome: "adopt_representative",
activeFocus: {
intent: "distinguish_candidates",
targetDomain: "relocation",
targetKind: "home_change",
},
});
assert.equal(plan.next_followup, null);
assert.equal(plan.session_outcome, "adopt_representative");
});
test("declined relationship skips to career and leaves horary uncovered", () => {
const plan = buildMethodFollowupPlan({
evidence: [{
@@ -993,6 +1007,123 @@ test("career evidence does not cover occupation; occupation still blocks until a
}), "collect_evidence");
});
test("draft occupation_note without a date covers occupation and unblocks offering", () => {
const plan = buildMethodFollowupPlan({
evidence: [
{ status: "confirmed", domain: "education", datePrecision: "year", occurredFrom: "2016-01-01", occurredTo: null },
{ status: "confirmed", domain: "relationship", datePrecision: "day", occurredFrom: "2024-05-01", occurredTo: null },
{ status: "confirmed", domain: "career", datePrecision: "day", occurredFrom: "2019-09-01", occurredTo: null },
{ status: "confirmed", domain: "family", datePrecision: "year", occurredFrom: "2020-01-01", occurredTo: null },
{
status: "draft",
domain: "occupation",
datePrecision: "unknown",
occurredFrom: null,
occurredTo: null,
eventKind: "occupation_note",
summary: "职业类型轨迹为技术开发",
},
],
});
assert.equal(plan.methods.find((item) => item.method_id === "occupation")?.status, "covered");
assert.notEqual(plan.next_followup?.method_id, "occupation");
assert.equal(conversationalSessionOutcome({
selectionAllowed: true,
proposeAllowed: true,
confirmationAllowed: false,
nextFollowup: plan.next_followup,
methods: plan.methods,
}), "adopt_representative");
});
test("stale occupation collect focus does not keep interviewing after occupation is covered", () => {
const plan = buildMethodFollowupPlan({
evidence: [
{ status: "confirmed", domain: "education", datePrecision: "year", occurredFrom: "2016-01-01", occurredTo: null },
{ status: "confirmed", domain: "relationship", datePrecision: "day", occurredFrom: "2024-05-01", occurredTo: null },
{ status: "confirmed", domain: "career", datePrecision: "day", occurredFrom: "2019-09-01", occurredTo: null },
{ status: "confirmed", domain: "family", datePrecision: "year", occurredFrom: "2020-01-01", occurredTo: null },
{
status: "draft",
domain: "occupation",
datePrecision: "unknown",
occurredFrom: null,
occurredTo: null,
eventKind: "occupation_note",
summary: "前端工程师",
},
],
activeFocus: {
intent: "collect_method_evidence",
targetDomain: "occupation",
targetKind: "occupation_note",
},
});
assert.notEqual(plan.next_followup?.method_id, "active_focus");
assert.notEqual(plan.next_followup?.method_id, "occupation");
assert.equal(conversationalSessionOutcome({
selectionAllowed: true,
proposeAllowed: true,
confirmationAllowed: false,
nextFollowup: plan.next_followup,
methods: plan.methods,
}), "adopt_representative");
});
test("event_probe does not block offering once blocking methods are covered", () => {
const plan = buildMethodFollowupPlan({
evidence: CLASSIC_COVERAGE.filter((item) => item.domain !== "horary"),
eventProbes: [{
year: 2018,
year_label: "2018 年前后",
domain: "relocation",
event_family: "搬家、离乡或长期异地",
source: "dasha_activation",
tracks: ["vimshottari", "narayana"],
tracks_agree: true,
unique_minute_claim: false,
user_meaning: "年份锁定 2018 年前后。请写成一句自然语言,问是否搬家。",
role: "reverse_verify",
}],
});
assert.equal(isOfferBlockingFollowup(plan.next_followup, plan.methods), false);
assert.equal(conversationalSessionOutcome({
selectionAllowed: true,
proposeAllowed: true,
confirmationAllowed: false,
nextFollowup: plan.next_followup,
methods: plan.methods,
}), "adopt_representative");
});
test("accepted time reverse-verifies an uncovered year in a covered domain", () => {
const plan = buildMethodFollowupPlan({
evidence: [{
status: "confirmed",
domain: "career",
datePrecision: "day",
occurredFrom: "2024-04-07",
occurredTo: null,
}],
accepted: true,
eventProbes: [{
year: 2018,
year_label: "2018 年前后",
domain: "career",
event_family: "入职、升职或职责明显加重",
source: "dasha_activation",
tracks: ["vimshottari", "narayana"],
tracks_agree: true,
unique_minute_claim: false,
user_meaning: "年份锁定 2018 年前后。请写成一句自然语言,问是否入职或职责加重。",
role: "reverse_verify",
}],
});
assert.equal(plan.next_followup?.source, "reverse_verify");
assert.equal(plan.next_followup?.domain, "career");
assert.equal(plan.next_followup?.choice_frame?.period, "2018 年前后");
});
test("declining occupation covers the method; declining horary is skipped_by_policy", () => {
const plan = buildMethodFollowupPlan({
evidence: [