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

This commit is contained in:
dctouch 2026-04-23 14:58:35 +03:00
parent f7a8844c90
commit 62e2b3323f
7 changed files with 366 additions and 3 deletions

View File

@ -0,0 +1,94 @@
{
"schema_version": "domain_truth_harness_spec_v1",
"scenario_id": "address_truth_harness_phase61_metadata_movement_pivot_year_switch",
"domain": "address_phase61_metadata_movement_pivot_year_switch",
"title": "Phase 61 metadata movement pivot year switch",
"description": "Targeted AGENT replay for Big Block F where a metadata-born document loop reaches bounded retrieval, pivots into movement evidence, and then survives a short year-switch follow-up without losing the selected lane, organization, or scoped proof path.",
"bindings": {},
"steps": [
{
"step_id": "step_01_metadata_ambiguity_surface",
"title": "Metadata ambiguity is surfaced honestly for VAT",
"question": "какие объекты 1С есть по НДС?",
"allowed_reply_types": ["partial_coverage", "factual_with_explanation"],
"required_answer_patterns_all": [
"(?i)metadata|метадан",
"(?i)ндс",
"(?i)документ|регистр"
],
"criticality": "critical",
"semantic_tags": ["metadata_surface", "mixed_ambiguity"]
},
{
"step_id": "step_02_neutral_followup_requires_lane_choice",
"title": "Neutral follow-up still requires lane choice",
"question": "давай дальше",
"allowed_reply_types": ["clarification_required", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ",
"(?i)движени|регистр",
"(?i)уточн|выб(ери|рать)|какой контур"
],
"criticality": "critical",
"semantic_tags": ["metadata_lane_choice_clarification", "neutral_followup"]
},
{
"step_id": "step_03_document_lane_with_org_keeps_only_period_gap",
"title": "Document lane plus organization in one follow-up leaves only the period gap",
"question": "по документам по ООО Альтернатива Плюс",
"allowed_reply_types": ["clarification_required", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ|счет|накладн|акт",
"(?i)период"
],
"criticality": "critical",
"semantic_tags": ["document_lane_after_clarification", "inline_organization_clarification"]
},
{
"step_id": "step_04_period_clarification_executes_same_document_loop",
"title": "Period clarification executes the same bounded document loop",
"question": "за 2020 год",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ|счет|сч[её]т[- ]?фактур|накладн|акт|строк"
],
"criticality": "critical",
"semantic_tags": ["document_lane_execution", "bounded_retrieval"]
},
{
"step_id": "step_05_movement_pivot_keeps_same_scope",
"title": "Short movement pivot reuses the same organization and period",
"question": "а теперь по движениям?",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)ндс|движени|регистр|операц|платеж|поступлен|списан|строк"
],
"forbidden_answer_patterns": [
"(?i)уточните .*организац",
"(?i)уточните .*период",
"(?i)уточните .*контур",
"(?i)не найден контрагент"
],
"criticality": "critical",
"semantic_tags": ["movement_pivot_after_document_retrieval", "scope_reuse", "same_proof_path_family_shift"]
},
{
"step_id": "step_06_year_switch_keeps_movement_lane",
"title": "Short year-switch stays in the movement lane after the pivot",
"question": "а теперь за 2021?",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)2021",
"(?i)ндс|движени|регистр|операц|платеж|поступлен|списан|строк"
],
"forbidden_answer_patterns": [
"(?i)документ|счет|накладн|акт",
"(?i)уточните .*организац",
"(?i)уточните .*период",
"(?i)не найден контрагент"
],
"criticality": "critical",
"semantic_tags": ["movement_lane_continuity", "year_switch_after_pivot", "same_scope_new_period"]
}
]
}

View File

@ -0,0 +1,95 @@
{
"schema_version": "domain_truth_harness_spec_v1",
"scenario_id": "address_truth_harness_phase62_metadata_movement_pivot_all_time",
"domain": "address_phase62_metadata_movement_pivot_all_time",
"title": "Phase 62 metadata movement pivot all-time follow-up",
"description": "Targeted AGENT replay for Big Block F where a metadata-born document loop reaches bounded retrieval, pivots into movement evidence, and then survives a short all-time follow-up without losing the selected lane, organization, or scoped proof path.",
"bindings": {},
"steps": [
{
"step_id": "step_01_metadata_ambiguity_surface",
"title": "Metadata ambiguity is surfaced honestly for VAT",
"question": "какие объекты 1С есть по НДС?",
"allowed_reply_types": ["partial_coverage", "factual_with_explanation"],
"required_answer_patterns_all": [
"(?i)metadata|метадан",
"(?i)ндс",
"(?i)документ|регистр"
],
"criticality": "critical",
"semantic_tags": ["metadata_surface", "mixed_ambiguity"]
},
{
"step_id": "step_02_neutral_followup_requires_lane_choice",
"title": "Neutral follow-up still requires lane choice",
"question": "давай дальше",
"allowed_reply_types": ["clarification_required", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ",
"(?i)движени|регистр",
"(?i)уточн|выб(ери|рать)|какой контур"
],
"criticality": "critical",
"semantic_tags": ["metadata_lane_choice_clarification", "neutral_followup"]
},
{
"step_id": "step_03_document_lane_with_org_keeps_only_period_gap",
"title": "Document lane plus organization in one follow-up leaves only the period gap",
"question": "по документам по ООО Альтернатива Плюс",
"allowed_reply_types": ["clarification_required", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ|счет|накладн|акт",
"(?i)период"
],
"criticality": "critical",
"semantic_tags": ["document_lane_after_clarification", "inline_organization_clarification"]
},
{
"step_id": "step_04_period_clarification_executes_same_document_loop",
"title": "Period clarification executes the same bounded document loop",
"question": "за 2020 год",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ|счет|сч[её]т[- ]?фактур|накладн|акт|строк"
],
"criticality": "critical",
"semantic_tags": ["document_lane_execution", "bounded_retrieval"]
},
{
"step_id": "step_05_movement_pivot_keeps_same_scope",
"title": "Short movement pivot reuses the same organization and period",
"question": "а теперь по движениям?",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)ндс|движени|регистр|операц|платеж|поступлен|списан|строк"
],
"forbidden_answer_patterns": [
"(?i)уточните .*организац",
"(?i)уточните .*период",
"(?i)уточните .*контур",
"(?i)не найден контрагент"
],
"criticality": "critical",
"semantic_tags": ["movement_pivot_after_document_retrieval", "scope_reuse", "same_proof_path_family_shift"]
},
{
"step_id": "step_06_all_time_followup_keeps_movement_lane",
"title": "All-time follow-up clears the previous period but stays in the movement lane after the pivot",
"question": "а теперь за все время?",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)все время|доступное время|весь период",
"(?i)ндс|движени|регистр|операц|платеж|поступлен|списан|строк"
],
"forbidden_answer_patterns": [
"(?i)за 2020",
"(?i)документ|счет|накладн|акт",
"(?i)уточните .*организац",
"(?i)уточните .*контур",
"(?i)не найден контрагент"
],
"criticality": "critical",
"semantic_tags": ["all_time_followup", "movement_lane_continuity", "period_cleared_after_pivot"]
}
]
}

View File

@ -0,0 +1,95 @@
{
"schema_version": "domain_truth_harness_spec_v1",
"scenario_id": "address_truth_harness_phase63_metadata_document_pivot_all_time",
"domain": "address_phase63_metadata_document_pivot_all_time",
"title": "Phase 63 metadata document pivot all-time follow-up",
"description": "Targeted AGENT replay for Big Block F where a metadata-born movement loop reaches bounded retrieval, pivots into document evidence, and then survives a short all-time follow-up without losing the selected lane, organization, or scoped proof path.",
"bindings": {},
"steps": [
{
"step_id": "step_01_metadata_ambiguity_surface",
"title": "Metadata ambiguity is surfaced honestly for VAT",
"question": "какие объекты 1С есть по НДС?",
"allowed_reply_types": ["partial_coverage", "factual_with_explanation"],
"required_answer_patterns_all": [
"(?i)metadata|метадан",
"(?i)ндс",
"(?i)документ|регистр"
],
"criticality": "critical",
"semantic_tags": ["metadata_surface", "mixed_ambiguity"]
},
{
"step_id": "step_02_neutral_followup_requires_lane_choice",
"title": "Neutral follow-up still requires lane choice",
"question": "давай дальше",
"allowed_reply_types": ["clarification_required", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)документ",
"(?i)движени|регистр",
"(?i)уточн|выб(ери|рать)|какой контур"
],
"criticality": "critical",
"semantic_tags": ["metadata_lane_choice_clarification", "neutral_followup"]
},
{
"step_id": "step_03_movement_lane_with_org_keeps_only_period_gap",
"title": "Movement lane plus organization in one follow-up leaves only the period gap",
"question": "по движениям по ООО Альтернатива Плюс",
"allowed_reply_types": ["clarification_required", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)движени|регистр",
"(?i)период"
],
"criticality": "critical",
"semantic_tags": ["movement_lane_after_clarification", "inline_organization_clarification"]
},
{
"step_id": "step_04_period_clarification_executes_same_movement_loop",
"title": "Period clarification executes the same bounded movement loop",
"question": "за 2020 год",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)ндс|движени|регистр|операц|платеж|поступлен|списан|строк"
],
"criticality": "critical",
"semantic_tags": ["movement_lane_execution", "bounded_retrieval"]
},
{
"step_id": "step_05_document_pivot_keeps_same_scope",
"title": "Short document pivot reuses the same organization and period",
"question": "а теперь по документам?",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)ндс|документ|счет|сч[её]т[- ]?фактур|накладн|акт|строк"
],
"forbidden_answer_patterns": [
"(?i)уточните .*организац",
"(?i)уточните .*период",
"(?i)уточните .*контур",
"(?i)не найден контрагент"
],
"criticality": "critical",
"semantic_tags": ["document_pivot_after_movement_retrieval", "scope_reuse", "same_proof_path_family_shift"]
},
{
"step_id": "step_06_all_time_followup_keeps_document_lane",
"title": "All-time follow-up clears the previous period but stays in the document lane after the pivot",
"question": "а теперь за все время?",
"allowed_reply_types": ["factual", "factual_with_explanation", "partial_coverage"],
"required_answer_patterns_all": [
"(?i)все время|доступное время|весь период",
"(?i)ндс|документ|счет|сч[её]т[- ]?фактур|накладн|акт|строк"
],
"forbidden_answer_patterns": [
"(?i)за 2020",
"(?i)движени|регистр",
"(?i)уточните .*организац",
"(?i)уточните .*контур",
"(?i)не найден контрагент"
],
"criticality": "critical",
"semantic_tags": ["all_time_followup", "document_lane_continuity", "period_cleared_after_pivot"]
}
]
}

View File

@ -85,7 +85,14 @@ const PRIMITIVE_CONTRACTS = [
supported_fact_families: ["document_evidence", "activity_lifecycle"],
supported_action_families: ["list_documents", "activity_duration"],
planning_tags: ["document"],
required_axes_any_of: [["document"], ["counterparty"], ["contract"], ["period", "organization"]],
required_axes_any_of: [
["document"],
["counterparty"],
["contract"],
["period", "organization"],
["all_time_scope", "counterparty"],
["all_time_scope", "organization"]
],
optional_axes: ["account", "amount", "item", "warehouse"],
output_fact_kinds: ["document_rows", "document_dates", "document_amounts"],
evidence_floor: "rows_matched",

View File

@ -118,7 +118,14 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
supported_fact_families: ["document_evidence", "activity_lifecycle"],
supported_action_families: ["list_documents", "activity_duration"],
planning_tags: ["document"],
required_axes_any_of: [["document"], ["counterparty"], ["contract"], ["period", "organization"]],
required_axes_any_of: [
["document"],
["counterparty"],
["contract"],
["period", "organization"],
["all_time_scope", "counterparty"],
["all_time_scope", "organization"]
],
optional_axes: ["account", "amount", "item", "warehouse"],
output_fact_kinds: ["document_rows", "document_dates", "document_amounts"],
evidence_floor: "rows_matched",

View File

@ -157,7 +157,9 @@ describe("assistant MCP catalog index", () => {
["document"],
["counterparty"],
["contract"],
["period", "organization"]
["period", "organization"],
["all_time_scope", "counterparty"],
["all_time_scope", "organization"]
]);
});
@ -180,6 +182,27 @@ describe("assistant MCP catalog index", () => {
expect(review.missing_axes_by_primitive).toEqual({});
});
it("marks an all-time organization-scoped document plan as catalog-compatible without requiring an explicit period", () => {
const plan = buildAssistantMcpDiscoveryPlan({
semanticDataNeed: "document evidence",
turnMeaning: {
asked_domain_family: "documents",
asked_action_family: "list_documents",
explicit_organization_scope: "ООО Альтернатива Плюс",
metadata_scope_hint: "НДС",
subject_resolution_optional: true
},
proposedPrimitives: ["query_documents", "probe_coverage"],
requiredAxes: ["organization", "all_time_scope", "metadata_scope", "coverage_target"]
});
const review = reviewAssistantMcpDiscoveryPlanAgainstCatalog(plan);
expect(review.review_status).toBe("catalog_compatible");
expect(review.reason_codes).toContain("catalog_plan_compatible");
expect(review.missing_axes_by_primitive).toEqual({});
});
it("preserves source-summary evidence floors for metadata and coverage primitives", () => {
expect(getAssistantMcpCatalogPrimitive("inspect_1c_metadata").evidence_floor).toBe("source_summary");
expect(getAssistantMcpCatalogPrimitive("probe_coverage").evidence_floor).toBe("source_summary");

View File

@ -905,4 +905,46 @@ describe("assistant MCP discovery planner", () => {
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_metadata_scoped_movement_from_data_need_graph");
});
it("keeps metadata-scoped document evidence execution-ready with all-time scope once organization is known", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
business_fact_family: "document_evidence",
action_family: "list_documents",
aggregation_need: null,
time_scope_need: "all_time_scope",
comparison_need: null,
ranking_need: null,
proof_expectation: "coverage_checked_fact",
clarification_gaps: [],
decomposition_candidates: ["fetch_scoped_documents", "probe_coverage"],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_unchecked_fact_totals"],
reason_codes: [
"data_need_graph_built",
"data_need_graph_metadata_scoped_open_lane_without_subject",
"data_need_graph_all_time_scope_hint"
]
},
turnMeaning: {
asked_domain_family: "documents",
asked_action_family: "list_documents",
metadata_scope_hint: "НДС",
subject_resolution_optional: true,
explicit_organization_scope: "ООО Альтернатива Плюс",
unsupported_but_understood_family: "document_evidence"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("document_evidence");
expect(result.proposed_primitives).toEqual(["query_documents", "probe_coverage"]);
expect(result.required_axes).toEqual(["organization", "metadata_scope", "all_time_scope", "coverage_target"]);
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_metadata_scoped_document_from_data_need_graph");
});
});