ARCH: замкнуть all-time continuity после metadata retrieval

This commit is contained in:
2026-04-23 14:23:04 +03:00
parent 4a6ac6bd99
commit 14465c7fde
6 changed files with 300 additions and 2 deletions
@@ -148,11 +148,20 @@ function explicitOrganizationScope(pilot) {
const normalized = value.trim();
return normalized.length > 0 ? normalized : null;
}
function hasAllTimeScope(pilot) {
return (dryRunHasAxis(pilot, "all_time_scope") ||
pilot.reason_codes.includes("mcp_discovery_all_time_scope_signal_detected") ||
pilot.dry_run.reason_codes.includes("mcp_discovery_all_time_scope_signal_detected"));
}
function documentOrMovementScopeRu(pilot) {
const entity = firstEntityCandidate(pilot);
const period = explicitDateScope(pilot);
const entityPart = entity ? ` по контрагенту ${entity}` : "";
const periodPart = period ? ` за ${period}` : " в проверенном окне";
const periodPart = period
? ` за ${period}`
: hasAllTimeScope(pilot)
? " за все доступное время"
: " в проверенном окне";
return `${entityPart}${periodPart}`;
}
function isMovementLaneClarification(pilot) {
@@ -200,11 +200,23 @@ function explicitOrganizationScope(pilot: AssistantMcpDiscoveryPilotExecutionCon
return normalized.length > 0 ? normalized : null;
}
function hasAllTimeScope(pilot: AssistantMcpDiscoveryPilotExecutionContract): boolean {
return (
dryRunHasAxis(pilot, "all_time_scope") ||
pilot.reason_codes.includes("mcp_discovery_all_time_scope_signal_detected") ||
pilot.dry_run.reason_codes.includes("mcp_discovery_all_time_scope_signal_detected")
);
}
function documentOrMovementScopeRu(pilot: AssistantMcpDiscoveryPilotExecutionContract): string {
const entity = firstEntityCandidate(pilot);
const period = explicitDateScope(pilot);
const entityPart = entity ? ` по контрагенту ${entity}` : "";
const periodPart = period ? ` за ${period}` : " в проверенном окне";
const periodPart = period
? ` за ${period}`
: hasAllTimeScope(pilot)
? " за все доступное время"
: " в проверенном окне";
return `${entityPart}${periodPart}`;
}
@@ -170,6 +170,51 @@ describe("assistant MCP discovery answer adapter", () => {
expect(draft.must_not_claim).toContain("Do not present the confirmed movement rows as a complete movement universe.");
});
it("renders metadata-scoped movement all-time follow-up as an all-time bounded answer", async () => {
const planner = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "movement_evidence",
action_family: "list_movements",
aggregation_need: null,
time_scope_need: "all_time_scope",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["collect_scoped_movements", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: ["data_need_graph_built", "data_need_graph_all_time_scope_hint"]
},
turnMeaning: {
asked_domain_family: "movements",
asked_action_family: "list_movements",
explicit_entity_candidates: [],
explicit_organization_scope: "ООО Альтернатива Плюс",
unsupported_but_understood_family: "movement_evidence"
}
});
const pilot = await executeAssistantMcpDiscoveryPilot(
planner,
buildCustomQueryDeps({
fetched_rows: 100,
matched_rows: 0,
rows: [],
raw_rows: [{ Period: "2020-06-30T00:00:00", Organization: "ООО Альтернатива Плюс", Registrar: "Move1" }]
})
);
const draft = buildAssistantMcpDiscoveryAnswerDraft(pilot);
expect(draft.answer_mode).toBe("bounded_inference_only");
expect(draft.headline).toContain("движени");
expect(draft.headline).toContain("все доступное время");
expect(draft.headline).not.toContain("за 2020");
expect(draft.inference_lines.join("\n")).not.toContain("за 2020");
});
it("keeps bounded-only movement answers tied to the resolved entity and checked period", async () => {
const planner = planAssistantMcpDiscovery({
turnMeaning: {