fix(rectification): offer representative time once event-fit is enough

Keep unique-top and width on confirmation only, and stop lagna-frame follow-ups from blocking cards on an already-scored cluster.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Jesse_Chen
2026-08-21 02:01:57 +08:00
co-authored by Cursor
parent 5fdabfae89
commit a88467ffa8
12 changed files with 180 additions and 41 deletions
@@ -2,7 +2,7 @@ import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import test from "node:test";
import { buildMethodFollowupPlan, buildNextUserAction, conversationalSessionOutcome } from "../src/lib/rectification-agentic/v9/method-followup.ts";
import { buildMethodFollowupPlan, buildNextUserAction, conversationalSessionOutcome, isOfferBlockingFollowup } from "../src/lib/rectification-agentic/v9/method-followup.ts";
import {
internalObservationsFromWindowScan,
parseWindowScan,
@@ -658,6 +658,7 @@ test("public tool surface stays at 13 and new cases bind 10.0.10", () => {
assert.match(skill, /method_followup_plan/);
assert.match(skill, /感情 → 事业 → 家人 → 外貌 → 疤痕 → 职业 → 占问/);
assert.match(skill, /KP 观察不计分、不挡提出门/);
assert.match(skill, /唯一领先和宽度≤5只挡确认门/);
assert.match(skill, /D9\/D10 类型表是校时方法/);
assert.doesNotMatch(skill, /±5 分钟确定性/);
assert.doesNotMatch(skill, /KP 政策跳过不挡提出门/);
@@ -728,7 +729,7 @@ test("family then appearance then marks then occupation then horary follow the m
}), "adopt_representative");
});
test("precision stage lagna_frame asks another dated event instead of rotating domains", () => {
test("precision stage lagna_frame waits for uncovered career before asking another dated event", () => {
const plan = buildMethodFollowupPlan({
evidence: [
{ status: "confirmed", domain: "education", datePrecision: "year", occurredFrom: "2016-01-01", occurredTo: null },
@@ -736,10 +737,27 @@ test("precision stage lagna_frame asks another dated event instead of rotating d
],
precisionStage: "lagna_frame",
});
assert.equal(plan.next_followup?.method_id, "d10_career");
assert.equal(plan.next_followup?.source, "method_coverage");
assert.equal(isOfferBlockingFollowup(plan.next_followup, plan.methods), true);
assert.doesNotMatch(JSON.stringify(plan), UNIQUE_MINUTE_COPY);
});
test("lagna_frame after classic coverage does not keep blocking representative time cards", () => {
const plan = buildMethodFollowupPlan({
evidence: CLASSIC_COVERAGE,
precisionStage: "lagna_frame",
});
assert.equal(plan.next_followup?.source, "precision_stage");
assert.equal(plan.next_followup?.ask_theme, "dated_event");
assert.match(plan.next_followup?.user_prompt_hint ?? "", /A\/B\/C\/D/);
assert.doesNotMatch(JSON.stringify(plan), UNIQUE_MINUTE_COPY);
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("precision stage d4 asks home change not family, and d5 asks education", () => {