Оформить business_overview как маршрутный контракт Open-World Breadth

This commit is contained in:
dctouch 2026-05-03 21:30:45 +03:00
parent 284b201912
commit e65b7fdaed
16 changed files with 513 additions and 20 deletions

View File

@ -14,7 +14,9 @@ If another document says `78%`, `87%`, `92%`, or `85%` for a module that is now
- `Inventory Stock Open-World Breadth Proof`: `100%` for the declared inventory-stock scenario pack, not for arbitrary inventory questions. - `Inventory Stock Open-World Breadth Proof`: `100%` for the declared inventory-stock scenario pack, not for arbitrary inventory questions.
- `Planner Autonomy Consolidation`: `100%` for the declared phase83 planner-brain slice, including catalog alignment, live-readiness gating, checked-source sanitation, and accepted mixed replay. - `Planner Autonomy Consolidation`: `100%` for the declared phase83 planner-brain slice, including catalog alignment, live-readiness gating, checked-source sanitation, and accepted mixed replay.
- Active next module: broader `Open-World Bounded Autonomy Breadth` over unfamiliar 1C asks, while keeping Post-F and phase83 as regression gates. - Active next module: broader `Open-World Bounded Autonomy Breadth` over unfamiliar 1C asks, while keeping Post-F and phase83 as regression gates.
- First active slice: `Business Overview Evidence Fusion`, tracked in `22 - open_world_bounded_autonomy_breadth_2026-05-01.md`. - Completed active slice: `Business Overview Evidence Fusion`, tracked in `22 - open_world_bounded_autonomy_breadth_2026-05-01.md`.
- Current active slice: `Business Overview Catalog Route Fabric`: the route is reviewed in catalog/data-need/planner contracts, while fresh multi-probe runtime execution remains a pending bridge.
- Active module progress: `~18% (Open-World Bounded Autonomy Breadth)`.
## Reporting Rule ## Reporting Rule
@ -51,6 +53,7 @@ The project is not yet a universal arbitrary-1C agent.
Remaining work belongs to the next breadth module: Remaining work belongs to the next breadth module:
- implement the fresh multi-probe `business_overview` runtime bridge behind the reviewed route-fabric contract;
- broader dynamic schema traversal for unfamiliar 1C asks; - broader dynamic schema traversal for unfamiliar 1C asks;
- more primitive descriptors where live evidence proves a real gap; - more primitive descriptors where live evidence proves a real gap;
- more replay-backed domain packs that start from user business meaning, not from route convenience; - more replay-backed domain packs that start from user business meaning, not from route convenience;

View File

@ -70,12 +70,28 @@ When this bridge answers, it must:
- keep profit/margin/debt/VAT as explicit missing evidence when not checked; - keep profit/margin/debt/VAT as explicit missing evidence when not checked;
- avoid raw MCP, planner, catalog, route, primitive, or debug wording. - avoid raw MCP, planner, catalog, route, primitive, or debug wording.
### Next Slice ## Slice 2 - Business Overview Catalog Route Fabric
This slice promotes the broad-evaluation contour from a living-chat bridge into the reviewed planner/catalog vocabulary.
### Current Implementation Boundary
Implemented now:
- `business_overview` exists as a reviewed catalog chain template;
- the data-need graph recognizes broad company analysis as a bounded business-overview evidence need;
- fresh business-overview probes require an organization scope instead of silently reusing stale context;
- planner output can select `business_overview` as the catalog top match with structured alignment telemetry;
- the pilot executor exposes `business_overview_route_template_v1` as an explicit scope, but returns an unsupported runtime boundary until the fresh multi-probe bridge is implemented.
This is deliberately not a fake runtime success.
The assistant now has the route-fabric contract for the next slice, while the live business overview still uses the safe evidence-fusion bridge from Slice 1.
### Still Pending Runtime Slice
Promote this bridge into a real planner route: Promote this bridge into a real planner route:
- add a reviewed `business_overview` catalog chain template;
- let the data-need graph model broad evaluation as a composed evidence need;
- run bounded fresh probes for year turnover, top customers, incoming/outgoing/net flow, debt, VAT, and inventory context where available; - run bounded fresh probes for year turnover, top customers, incoming/outgoing/net flow, debt, VAT, and inventory context where available;
- return a layered analyst answer with exact evidence, bounded inference, unknowns, and recommended next probes. - return a layered analyst answer with exact evidence, bounded inference, unknowns, and recommended next probes.
@ -98,4 +114,9 @@ Initial local validation:
- `npm.cmd run build`: passed. - `npm.cmd run build`: passed.
- graphify rebuild: `5977 nodes`, `12983 edges`, `137 communities`. - graphify rebuild: `5977 nodes`, `12983 edges`, `137 communities`.
Business-overview route-fabric validation:
- `npm.cmd test -- assistantMcpCatalogIndex.test.ts assistantMcpDiscoveryDataNeedGraph.test.ts assistantMcpDiscoveryPlanner.test.ts assistantMcpDiscoveryPilotExecutor.test.ts`: passed `102/102`.
- fresh multi-probe runtime execution remains intentionally pending behind `business_overview_route_template_v1`.
Graphify must be rebuilt after this code/doc slice before commit. Graphify must be rebuilt after this code/doc slice before commit.

View File

@ -51,6 +51,7 @@ Status canon for planning:
- Planner Autonomy Consolidation is closed at `100%` for the declared phase83 planner-brain slice. - Planner Autonomy Consolidation is closed at `100%` for the declared phase83 planner-brain slice.
- The active next module is now `Open-World Bounded Autonomy Breadth` over unfamiliar 1C asks, with Post-F and phase83 retained as semantic canaries. - The active next module is now `Open-World Bounded Autonomy Breadth` over unfamiliar 1C asks, with Post-F and phase83 retained as semantic canaries.
- The first active slice is `Business Overview Evidence Fusion`: broad company-analysis wording now produces a richer evidence-grounded business overview from confirmed MCP/session facts instead of a thin generic summary. - The first active slice is `Business Overview Evidence Fusion`: broad company-analysis wording now produces a richer evidence-grounded business overview from confirmed MCP/session facts instead of a thin generic summary.
- The current follow-up slice is `Business Overview Catalog Route Fabric`: `business_overview` is now a reviewed catalog/data-need/planner chain, while fresh multi-probe execution remains honestly bounded behind an unsupported runtime scope until the next bridge is implemented.
- The short source of truth for status wording is [21 - current_status_canon_2026-05-01.md](./21%20-%20current_status_canon_2026-05-01.md). - The short source of truth for status wording is [21 - current_status_canon_2026-05-01.md](./21%20-%20current_status_canon_2026-05-01.md).
It now documents a turnaround that is already operational in code, already materially past the acute regression breakpoint, and already moved through bounded MCP autonomy, Post-F hardening, inventory breadth proof, and the declared Planner Autonomy slice: It now documents a turnaround that is already operational in code, already materially past the acute regression breakpoint, and already moved through bounded MCP autonomy, Post-F hardening, inventory breadth proof, and the declared Planner Autonomy slice:
@ -114,8 +115,8 @@ Current honest status:
- exit-from-danger-zone readiness: `~97%` - exit-from-danger-zone readiness: `~97%`
- pre-multidomain readiness: `~90%` - pre-multidomain readiness: `~90%`
- bounded-autonomy foundation readiness: `~89%` - bounded-autonomy foundation readiness: `~89%`
- open-world bounded-autonomy readiness: `~85%` - open-world bounded-autonomy readiness: `~86%`
- active Open-World Bounded Autonomy Breadth progress: `~12%`, with the first business-overview evidence-fusion slice started and locally tested; fresh multi-probe planner route is still pending - active Open-World Bounded Autonomy Breadth progress: `~18%`, with business-overview evidence fusion and the reviewed `business_overview` catalog/data-need/planner route-fabric slice locally tested; fresh multi-probe runtime execution is still pending
- Post-F semantic integrity module progress: `~99%` operationally closed, with remaining risk now treated as next-slice discovery rather than an open blocker inside the closed slice - Post-F semantic integrity module progress: `~99%` operationally closed, with remaining risk now treated as next-slice discovery rather than an open blocker inside the closed slice
- active inventory-stock breadth slice progress: `100%` for the declared scenario pack, not for arbitrary inventory questions - active inventory-stock breadth slice progress: `100%` for the declared scenario pack, not for arbitrary inventory questions
- Planner Autonomy Consolidation progress: `100%` for the declared module, with catalog-fabric, value-flow arbitration, lifecycle bounded inference, broad-evaluation bridge, inventory catalog templates, inventory runtime-boundary honesty, exact inventory recipe bridging, unambiguous metadata-surface lane inference, catalog chain-template scoring, structured chain-match contract exposure, runtime/debug propagation, subject-aware bidirectional comparison arbitration, structured catalog-alignment verdicts, representative alignment regression guard, catalog-alignment reason-code telemetry, explicit `alignment_status` propagation, truth-harness/acceptance-matrix surfacing, soft divergence warning, `catalog_alignment_ok` acceptance invariant, step-level expected catalog-alignment assertions, phase66 and phase32 spec alignment expectations, AGENT source-catalog surfacing, generated phase83 mixed planner-brain replay spec, checked-source user-facing error sanitation, surface-grounded catalog promotion, and guarded live phase83 acceptance validated. Broader unfamiliar 1C asks are now next-module breadth work rather than an open blocker inside this declared slice - Planner Autonomy Consolidation progress: `100%` for the declared module, with catalog-fabric, value-flow arbitration, lifecycle bounded inference, broad-evaluation bridge, inventory catalog templates, inventory runtime-boundary honesty, exact inventory recipe bridging, unambiguous metadata-surface lane inference, catalog chain-template scoring, structured chain-match contract exposure, runtime/debug propagation, subject-aware bidirectional comparison arbitration, structured catalog-alignment verdicts, representative alignment regression guard, catalog-alignment reason-code telemetry, explicit `alignment_status` propagation, truth-harness/acceptance-matrix surfacing, soft divergence warning, `catalog_alignment_ok` acceptance invariant, step-level expected catalog-alignment assertions, phase66 and phase32 spec alignment expectations, AGENT source-catalog surfacing, generated phase83 mixed planner-brain replay spec, checked-source user-facing error sanitation, surface-grounded catalog promotion, and guarded live phase83 acceptance validated. Broader unfamiliar 1C asks are now next-module breadth work rather than an open blocker inside this declared slice
@ -159,6 +160,7 @@ Latest live proof now includes:
- lifecycle/value-flow Planner Autonomy response gate accepted: `address_truth_harness_phase19_mcp_discovery_response_gate_planner_lifecycle_rerun4` accepted `8/8`, proving bounded lifecycle inference, current-turn value-flow aggregate arbitration, and sanitized evidence wording - lifecycle/value-flow Planner Autonomy response gate accepted: `address_truth_harness_phase19_mcp_discovery_response_gate_planner_lifecycle_rerun4` accepted `8/8`, proving bounded lifecycle inference, current-turn value-flow aggregate arbitration, and sanitized evidence wording
- broad-evaluation bridge continuity accepted: `address_truth_harness_phase21_net_followup_after_broad_eval_planner_lifecycle_rerun2` accepted `3/3` and `address_truth_harness_phase22_broad_business_evaluation_bridge_planner_lifecycle_rerun2` accepted `3/3` - broad-evaluation bridge continuity accepted: `address_truth_harness_phase21_net_followup_after_broad_eval_planner_lifecycle_rerun2` accepted `3/3` and `address_truth_harness_phase22_broad_business_evaluation_bridge_planner_lifecycle_rerun2` accepted `3/3`
- latest local Planner Autonomy slice accepted: full MCP-discovery suite passed `268/268` with `9` skipped; broad MCP/living-chat/route/meaning slice passed `305/305` with `9` skipped; build passed - latest local Planner Autonomy slice accepted: full MCP-discovery suite passed `268/268` with `9` skipped; broad MCP/living-chat/route/meaning slice passed `305/305` with `9` skipped; build passed
- business-overview route-fabric slice accepted locally: catalog/data-need/planner/pilot boundary slice passed `102/102`; the pilot executor exposes `business_overview_route_template_v1` as an explicit unsupported scope until the fresh multi-probe bridge exists
- inventory template lift accepted locally: catalog/data-need/planner/turn-input slice passed `139/139` with `6` skipped; full MCP-discovery slice passed `276/276` with `9` skipped; build passed; graphify stayed at `5912 nodes`, `12833 edges`, `138 communities` - inventory template lift accepted locally: catalog/data-need/planner/turn-input slice passed `139/139` with `6` skipped; full MCP-discovery slice passed `276/276` with `9` skipped; build passed; graphify stayed at `5912 nodes`, `12833 edges`, `138 communities`
- inventory runtime-boundary hardening accepted locally: runtime-bridge/answer-adapter/pilot-executor slice passed `68/68` with `1` skipped; full MCP-discovery slice passed `277/277` with `9` skipped; build passed; graphify rebuilt to `5913 nodes`, `12837 edges`, `138 communities` - inventory runtime-boundary hardening accepted locally: runtime-bridge/answer-adapter/pilot-executor slice passed `68/68` with `1` skipped; full MCP-discovery slice passed `277/277` with `9` skipped; build passed; graphify rebuilt to `5913 nodes`, `12837 edges`, `138 communities`
- inventory exact-runtime bridge accepted locally: runtime-bridge/answer-adapter/pilot-executor slice passed `70/70` with `1` skipped; full MCP-discovery slice passed `279/279` with `9` skipped; build passed; graphify rebuilt to `5930 nodes`, `12884 edges`, `135 communities` - inventory exact-runtime bridge accepted locally: runtime-bridge/answer-adapter/pilot-executor slice passed `70/70` with `1` skipped; full MCP-discovery slice passed `279/279` with `9` skipped; build passed; graphify rebuilt to `5930 nodes`, `12884 edges`, `135 communities`

View File

@ -51,6 +51,7 @@ const PRIMITIVE_CONTRACTS = [
"document_evidence", "document_evidence",
"movement_evidence", "movement_evidence",
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
"inventory_supplier_overlap" "inventory_supplier_overlap"
@ -63,6 +64,7 @@ const PRIMITIVE_CONTRACTS = [
"list_documents", "list_documents",
"list_movements", "list_movements",
"activity_duration", "activity_duration",
"broad_evaluation",
"purchase_provenance", "purchase_provenance",
"sale_trace", "sale_trace",
"supplier_overlap" "supplier_overlap"
@ -84,8 +86,22 @@ const PRIMITIVE_CONTRACTS = [
"collect_outgoing_movements", "collect_outgoing_movements",
"fetch_scoped_movements" "fetch_scoped_movements"
], ],
supported_fact_families: ["value_flow", "movement_evidence", "inventory_stock_snapshot", "inventory_supplier_overlap"], supported_fact_families: [
supported_action_families: ["turnover", "payout", "net_value_flow", "list_movements", "stock_snapshot", "supplier_overlap"], "value_flow",
"movement_evidence",
"business_overview",
"inventory_stock_snapshot",
"inventory_supplier_overlap"
],
supported_action_families: [
"turnover",
"payout",
"net_value_flow",
"list_movements",
"broad_evaluation",
"stock_snapshot",
"supplier_overlap"
],
planning_tags: ["movement", "comparison", "ranking", "aggregation", "monthly_aggregation"], planning_tags: ["movement", "comparison", "ranking", "aggregation", "monthly_aggregation"],
required_axes_any_of: [ required_axes_any_of: [
["period", "account"], ["period", "account"],
@ -110,11 +126,19 @@ const PRIMITIVE_CONTRACTS = [
supported_fact_families: [ supported_fact_families: [
"document_evidence", "document_evidence",
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
"inventory_supplier_overlap" "inventory_supplier_overlap"
], ],
supported_action_families: ["list_documents", "activity_duration", "purchase_provenance", "sale_trace", "supplier_overlap"], supported_action_families: [
"list_documents",
"activity_duration",
"broad_evaluation",
"purchase_provenance",
"sale_trace",
"supplier_overlap"
],
planning_tags: ["document"], planning_tags: ["document"],
required_axes_any_of: [ required_axes_any_of: [
["document"], ["document"],
@ -136,8 +160,8 @@ const PRIMITIVE_CONTRACTS = [
primitive_id: "aggregate_by_axis", primitive_id: "aggregate_by_axis",
purpose: "Aggregate already-scoped 1C evidence by a business axis such as counterparty, contract, or period.", purpose: "Aggregate already-scoped 1C evidence by a business axis such as counterparty, contract, or period.",
decomposition_hints: ["aggregate_checked_amounts", "aggregate_ranked_axis_values", "aggregate_by_month"], decomposition_hints: ["aggregate_checked_amounts", "aggregate_ranked_axis_values", "aggregate_by_month"],
supported_fact_families: ["value_flow", "inventory_stock_snapshot", "inventory_supplier_overlap"], supported_fact_families: ["value_flow", "business_overview", "inventory_stock_snapshot", "inventory_supplier_overlap"],
supported_action_families: ["turnover", "payout", "net_value_flow", "stock_snapshot", "supplier_overlap"], supported_action_families: ["turnover", "payout", "net_value_flow", "broad_evaluation", "stock_snapshot", "supplier_overlap"],
planning_tags: ["aggregation", "ranking", "monthly_aggregation"], planning_tags: ["aggregation", "ranking", "monthly_aggregation"],
required_axes_any_of: [ required_axes_any_of: [
["aggregate_axis", "period"], ["aggregate_axis", "period"],
@ -178,6 +202,7 @@ const PRIMITIVE_CONTRACTS = [
"document_evidence", "document_evidence",
"movement_evidence", "movement_evidence",
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_stock_snapshot", "inventory_stock_snapshot",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
@ -196,6 +221,7 @@ const PRIMITIVE_CONTRACTS = [
"list_documents", "list_documents",
"list_movements", "list_movements",
"activity_duration", "activity_duration",
"broad_evaluation",
"stock_snapshot", "stock_snapshot",
"purchase_provenance", "purchase_provenance",
"sale_trace", "sale_trace",
@ -216,6 +242,7 @@ const PRIMITIVE_CONTRACTS = [
decomposition_hints: ["explain_evidence_basis"], decomposition_hints: ["explain_evidence_basis"],
supported_fact_families: [ supported_fact_families: [
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_stock_snapshot", "inventory_stock_snapshot",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
@ -223,13 +250,14 @@ const PRIMITIVE_CONTRACTS = [
], ],
supported_action_families: [ supported_action_families: [
"activity_duration", "activity_duration",
"broad_evaluation",
"stock_snapshot", "stock_snapshot",
"purchase_provenance", "purchase_provenance",
"sale_trace", "sale_trace",
"supplier_overlap", "supplier_overlap",
"purchase_to_sale_chain" "purchase_to_sale_chain"
], ],
planning_tags: ["explanation", "inventory"], planning_tags: ["explanation", "inventory", "business_overview", "bounded_inference"],
required_axes_any_of: [["evidence_basis"], ["primitive_id"], ["source_rows_summary"]], required_axes_any_of: [["evidence_basis"], ["primitive_id"], ["source_rows_summary"]],
optional_axes: ["coverage_target", "domain_family", "item", "warehouse", "as_of_date", "supplier", "buyer"], optional_axes: ["coverage_target", "domain_family", "item", "warehouse", "as_of_date", "supplier", "buyer"],
output_fact_kinds: ["confirmed_facts", "inferred_facts", "unknown_facts"], output_fact_kinds: ["confirmed_facts", "inferred_facts", "unknown_facts"],
@ -414,6 +442,24 @@ const CHAIN_TEMPLATES = [
planning_tags: ["document", "explanation", "coverage", "bounded_inference", "activity_window", "legal_fact_boundary"], planning_tags: ["document", "explanation", "coverage", "bounded_inference", "activity_window", "legal_fact_boundary"],
safe_for_model_planning: true, safe_for_model_planning: true,
requires_evidence_gate: true requires_evidence_gate: true
},
{
chain_id: "business_overview",
semantic_data_need: "business overview evidence with bounded analyst interpretation",
chain_summary: "Collect organization-scoped movement and document evidence, aggregate checked business signals, probe coverage, and explain profit/margin limits before giving a bounded analyst overview.",
fallback_primitives: [
"query_movements",
"aggregate_by_axis",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
],
base_required_axes: ["organization", "aggregate_axis", "amount", "coverage_target", "evidence_basis", "profit_margin_boundary"],
supported_fact_families: ["business_overview"],
supported_action_families: ["broad_evaluation"],
planning_tags: ["business_overview", "movement", "document", "aggregation", "coverage", "explanation", "bounded_inference"],
safe_for_model_planning: true,
requires_evidence_gate: true
} }
]; ];
const CHAIN_TEMPLATE_MAP = new Map(CHAIN_TEMPLATES.map((template) => [template.chain_id, template])); const CHAIN_TEMPLATE_MAP = new Map(CHAIN_TEMPLATES.map((template) => [template.chain_id, template]));
@ -477,6 +523,15 @@ function tagSetFromFactAxisInput(input) {
if (input.business_fact_family === "value_flow") { if (input.business_fact_family === "value_flow") {
tags.add("movement"); tags.add("movement");
} }
if (input.business_fact_family === "business_overview") {
tags.add("business_overview");
tags.add("movement");
tags.add("document");
tags.add("aggregation");
tags.add("coverage");
tags.add("explanation");
tags.add("bounded_inference");
}
if (input.business_fact_family?.startsWith("inventory_")) { if (input.business_fact_family?.startsWith("inventory_")) {
tags.add("inventory"); tags.add("inventory");
} }

View File

@ -44,6 +44,14 @@ function businessFactFamilyFor(input) {
if (combined.includes("entity discovery") || combined.includes("entity_resolution")) { if (combined.includes("entity discovery") || combined.includes("entity_resolution")) {
return "entity_grounding"; return "entity_grounding";
} }
if (combined.includes("broad_business_evaluation") ||
combined.includes("broad_evaluation") ||
combined.includes("business overview") ||
combined.includes("business_overview") ||
combined.includes("company analysis") ||
combined.includes("business audit")) {
return "business_overview";
}
if (combined.includes("inventory") || if (combined.includes("inventory") ||
combined.includes("stock") || combined.includes("stock") ||
combined.includes("warehouse") || combined.includes("warehouse") ||
@ -113,6 +121,9 @@ function timeScopeNeedFor(input) {
if (input.family === "activity_lifecycle") { if (input.family === "activity_lifecycle") {
return "open_activity_window"; return "open_activity_window";
} }
if (input.family === "business_overview") {
return input.explicitDateScope ? "explicit_period" : "all_time_scope";
}
if (input.family === "inventory_stock_snapshot" || input.family === "inventory_supplier_overlap") { if (input.family === "inventory_stock_snapshot" || input.family === "inventory_supplier_overlap") {
return input.explicitDateScope ? "explicit_period" : "as_of_date_required"; return input.explicitDateScope ? "explicit_period" : "as_of_date_required";
} }
@ -193,6 +204,9 @@ function proofExpectationFor(input) {
if (input.family === "activity_lifecycle") { if (input.family === "activity_lifecycle") {
return "bounded_inference"; return "bounded_inference";
} }
if (input.family === "business_overview") {
return "bounded_inference";
}
return "coverage_checked_fact"; return "coverage_checked_fact";
} }
function decompositionCandidatesFor(input) { function decompositionCandidatesFor(input) {
@ -264,6 +278,15 @@ function decompositionCandidatesFor(input) {
pushUnique(result, "explain_evidence_basis"); pushUnique(result, "explain_evidence_basis");
return result; return result;
} }
if (input.family === "business_overview") {
pushUnique(result, "collect_scoped_movements");
pushUnique(result, "aggregate_checked_amounts");
pushUnique(result, "aggregate_ranked_axis_values");
pushUnique(result, "fetch_supporting_documents");
pushUnique(result, "probe_coverage");
pushUnique(result, "explain_evidence_basis");
return result;
}
if (input.family === "inventory_stock_snapshot") { if (input.family === "inventory_stock_snapshot") {
pushUnique(result, "fetch_scoped_movements"); pushUnique(result, "fetch_scoped_movements");
pushUnique(result, "aggregate_checked_amounts"); pushUnique(result, "aggregate_checked_amounts");
@ -300,6 +323,11 @@ function forbiddenOverclaimFlagsFor(family) {
if (family === "activity_lifecycle") { if (family === "activity_lifecycle") {
pushUnique(result, "no_legal_age_claim_without_evidence"); pushUnique(result, "no_legal_age_claim_without_evidence");
} }
if (family === "business_overview") {
pushUnique(result, "no_unchecked_fact_totals");
pushUnique(result, "no_unchecked_business_health_claim");
pushUnique(result, "no_profit_or_margin_claim_without_evidence");
}
if (family === "value_flow" || family === "movement_evidence" || family === "document_evidence") { if (family === "value_flow" || family === "movement_evidence" || family === "document_evidence") {
pushUnique(result, "no_unchecked_fact_totals"); pushUnique(result, "no_unchecked_fact_totals");
} }
@ -372,8 +400,14 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
!explicitOrganizationScope) { !explicitOrganizationScope) {
pushUnique(clarificationGaps, "organization"); pushUnique(clarificationGaps, "organization");
} }
else if (subjectCandidates.length === 0 &&
businessFactFamily === "business_overview" &&
!explicitOrganizationScope) {
pushUnique(clarificationGaps, "organization");
}
else if (subjectCandidates.length === 0 && else if (subjectCandidates.length === 0 &&
businessFactFamily !== "schema_surface" && businessFactFamily !== "schema_surface" &&
businessFactFamily !== "business_overview" &&
!openScopeWithoutSubject && !openScopeWithoutSubject &&
!metadataScopedOpenLaneWithoutSubject && !metadataScopedOpenLaneWithoutSubject &&
!inventoryStockSnapshotWithoutSubject) { !inventoryStockSnapshotWithoutSubject) {
@ -425,6 +459,9 @@ function buildAssistantMcpDiscoveryDataNeedGraph(input) {
if (allTimeScopeHint) { if (allTimeScopeHint) {
pushReason(reasonCodes, "data_need_graph_all_time_scope_hint"); pushReason(reasonCodes, "data_need_graph_all_time_scope_hint");
} }
if (businessFactFamily === "business_overview" && !explicitDateScope) {
pushReason(reasonCodes, "data_need_graph_business_overview_defaults_to_all_time_scope");
}
if (clarificationGaps.includes("organization")) { if (clarificationGaps.includes("organization")) {
pushReason(reasonCodes, "data_need_graph_open_scope_total_needs_organization"); pushReason(reasonCodes, "data_need_graph_open_scope_total_needs_organization");
} }

View File

@ -2065,6 +2065,8 @@ function pilotScopeForPlanner(planner) {
case "value_flow_ranking": case "value_flow_ranking":
case "value_flow": case "value_flow":
return valueFlowPilotProfile(planner).scope; return valueFlowPilotProfile(planner).scope;
case "business_overview":
return "business_overview_route_template_v1";
case "document_evidence": case "document_evidence":
return "counterparty_document_evidence_query_documents_v1"; return "counterparty_document_evidence_query_documents_v1";
case "lifecycle": case "lifecycle":

View File

@ -676,6 +676,31 @@ function recipeFor(input) {
extraReasons: primitiveSelection.reasonCodes extraReasons: primitiveSelection.reasonCodes
}); });
} }
if (graphFactFamily === "business_overview") {
pushUnique(axes, "organization");
pushUnique(axes, "aggregate_axis");
pushUnique(axes, "amount");
pushUnique(axes, "coverage_target");
pushUnique(axes, "evidence_basis");
pushUnique(axes, "profit_margin_boundary");
const template = (0, assistantMcpCatalogIndex_1.getAssistantMcpCatalogChainTemplate)("business_overview");
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
fallbackPrimitives: template.fallback_primitives,
requiredAxes: axes,
metadataSurface: input.metadataSurface,
actionFamily: action || graphAction,
allowAggregateByAxis: true,
selectedChainId: "business_overview"
});
return recipeFromCatalogChainTemplate({
chainId: "business_overview",
axes,
primitives: primitiveSelection.primitives,
reason: "planner_selected_business_overview_from_data_need_graph",
extraReasons: primitiveSelection.reasonCodes
});
}
if (graphFactFamily === "activity_lifecycle") { if (graphFactFamily === "activity_lifecycle") {
pushUnique(axes, "document_date"); pushUnique(axes, "document_date");
pushUnique(axes, "coverage_target"); pushUnique(axes, "coverage_target");

View File

@ -20,6 +20,7 @@ export type AssistantMcpCatalogChainTemplateId =
| "value_flow_comparison" | "value_flow_comparison"
| "value_flow_ranking" | "value_flow_ranking"
| "lifecycle" | "lifecycle"
| "business_overview"
| "movement_evidence" | "movement_evidence"
| "document_evidence" | "document_evidence"
| "entity_resolution"; | "entity_resolution";
@ -110,6 +111,7 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
"document_evidence", "document_evidence",
"movement_evidence", "movement_evidence",
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
"inventory_supplier_overlap" "inventory_supplier_overlap"
@ -122,6 +124,7 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
"list_documents", "list_documents",
"list_movements", "list_movements",
"activity_duration", "activity_duration",
"broad_evaluation",
"purchase_provenance", "purchase_provenance",
"sale_trace", "sale_trace",
"supplier_overlap" "supplier_overlap"
@ -143,8 +146,22 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
"collect_outgoing_movements", "collect_outgoing_movements",
"fetch_scoped_movements" "fetch_scoped_movements"
], ],
supported_fact_families: ["value_flow", "movement_evidence", "inventory_stock_snapshot", "inventory_supplier_overlap"], supported_fact_families: [
supported_action_families: ["turnover", "payout", "net_value_flow", "list_movements", "stock_snapshot", "supplier_overlap"], "value_flow",
"movement_evidence",
"business_overview",
"inventory_stock_snapshot",
"inventory_supplier_overlap"
],
supported_action_families: [
"turnover",
"payout",
"net_value_flow",
"list_movements",
"broad_evaluation",
"stock_snapshot",
"supplier_overlap"
],
planning_tags: ["movement", "comparison", "ranking", "aggregation", "monthly_aggregation"], planning_tags: ["movement", "comparison", "ranking", "aggregation", "monthly_aggregation"],
required_axes_any_of: [ required_axes_any_of: [
["period", "account"], ["period", "account"],
@ -169,11 +186,19 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
supported_fact_families: [ supported_fact_families: [
"document_evidence", "document_evidence",
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
"inventory_supplier_overlap" "inventory_supplier_overlap"
], ],
supported_action_families: ["list_documents", "activity_duration", "purchase_provenance", "sale_trace", "supplier_overlap"], supported_action_families: [
"list_documents",
"activity_duration",
"broad_evaluation",
"purchase_provenance",
"sale_trace",
"supplier_overlap"
],
planning_tags: ["document"], planning_tags: ["document"],
required_axes_any_of: [ required_axes_any_of: [
["document"], ["document"],
@ -195,8 +220,8 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
primitive_id: "aggregate_by_axis", primitive_id: "aggregate_by_axis",
purpose: "Aggregate already-scoped 1C evidence by a business axis such as counterparty, contract, or period.", purpose: "Aggregate already-scoped 1C evidence by a business axis such as counterparty, contract, or period.",
decomposition_hints: ["aggregate_checked_amounts", "aggregate_ranked_axis_values", "aggregate_by_month"], decomposition_hints: ["aggregate_checked_amounts", "aggregate_ranked_axis_values", "aggregate_by_month"],
supported_fact_families: ["value_flow", "inventory_stock_snapshot", "inventory_supplier_overlap"], supported_fact_families: ["value_flow", "business_overview", "inventory_stock_snapshot", "inventory_supplier_overlap"],
supported_action_families: ["turnover", "payout", "net_value_flow", "stock_snapshot", "supplier_overlap"], supported_action_families: ["turnover", "payout", "net_value_flow", "broad_evaluation", "stock_snapshot", "supplier_overlap"],
planning_tags: ["aggregation", "ranking", "monthly_aggregation"], planning_tags: ["aggregation", "ranking", "monthly_aggregation"],
required_axes_any_of: [ required_axes_any_of: [
["aggregate_axis", "period"], ["aggregate_axis", "period"],
@ -237,6 +262,7 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
"document_evidence", "document_evidence",
"movement_evidence", "movement_evidence",
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_stock_snapshot", "inventory_stock_snapshot",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
@ -255,6 +281,7 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
"list_documents", "list_documents",
"list_movements", "list_movements",
"activity_duration", "activity_duration",
"broad_evaluation",
"stock_snapshot", "stock_snapshot",
"purchase_provenance", "purchase_provenance",
"sale_trace", "sale_trace",
@ -275,6 +302,7 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
decomposition_hints: ["explain_evidence_basis"], decomposition_hints: ["explain_evidence_basis"],
supported_fact_families: [ supported_fact_families: [
"activity_lifecycle", "activity_lifecycle",
"business_overview",
"inventory_stock_snapshot", "inventory_stock_snapshot",
"inventory_purchase_provenance", "inventory_purchase_provenance",
"inventory_sale_trace", "inventory_sale_trace",
@ -282,13 +310,14 @@ const PRIMITIVE_CONTRACTS: AssistantMcpCatalogPrimitiveContract[] = [
], ],
supported_action_families: [ supported_action_families: [
"activity_duration", "activity_duration",
"broad_evaluation",
"stock_snapshot", "stock_snapshot",
"purchase_provenance", "purchase_provenance",
"sale_trace", "sale_trace",
"supplier_overlap", "supplier_overlap",
"purchase_to_sale_chain" "purchase_to_sale_chain"
], ],
planning_tags: ["explanation", "inventory"], planning_tags: ["explanation", "inventory", "business_overview", "bounded_inference"],
required_axes_any_of: [["evidence_basis"], ["primitive_id"], ["source_rows_summary"]], required_axes_any_of: [["evidence_basis"], ["primitive_id"], ["source_rows_summary"]],
optional_axes: ["coverage_target", "domain_family", "item", "warehouse", "as_of_date", "supplier", "buyer"], optional_axes: ["coverage_target", "domain_family", "item", "warehouse", "as_of_date", "supplier", "buyer"],
output_fact_kinds: ["confirmed_facts", "inferred_facts", "unknown_facts"], output_fact_kinds: ["confirmed_facts", "inferred_facts", "unknown_facts"],
@ -487,6 +516,25 @@ const CHAIN_TEMPLATES: AssistantMcpCatalogChainTemplateContract[] = [
planning_tags: ["document", "explanation", "coverage", "bounded_inference", "activity_window", "legal_fact_boundary"], planning_tags: ["document", "explanation", "coverage", "bounded_inference", "activity_window", "legal_fact_boundary"],
safe_for_model_planning: true, safe_for_model_planning: true,
requires_evidence_gate: true requires_evidence_gate: true
},
{
chain_id: "business_overview",
semantic_data_need: "business overview evidence with bounded analyst interpretation",
chain_summary:
"Collect organization-scoped movement and document evidence, aggregate checked business signals, probe coverage, and explain profit/margin limits before giving a bounded analyst overview.",
fallback_primitives: [
"query_movements",
"aggregate_by_axis",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
],
base_required_axes: ["organization", "aggregate_axis", "amount", "coverage_target", "evidence_basis", "profit_margin_boundary"],
supported_fact_families: ["business_overview"],
supported_action_families: ["broad_evaluation"],
planning_tags: ["business_overview", "movement", "document", "aggregation", "coverage", "explanation", "bounded_inference"],
safe_for_model_planning: true,
requires_evidence_gate: true
} }
]; ];
@ -564,6 +612,15 @@ function tagSetFromFactAxisInput(input: AssistantMcpCatalogFactAxisSearchInput):
if (input.business_fact_family === "value_flow") { if (input.business_fact_family === "value_flow") {
tags.add("movement"); tags.add("movement");
} }
if (input.business_fact_family === "business_overview") {
tags.add("business_overview");
tags.add("movement");
tags.add("document");
tags.add("aggregation");
tags.add("coverage");
tags.add("explanation");
tags.add("bounded_inference");
}
if (input.business_fact_family?.startsWith("inventory_")) { if (input.business_fact_family?.startsWith("inventory_")) {
tags.add("inventory"); tags.add("inventory");
} }

View File

@ -86,6 +86,16 @@ function businessFactFamilyFor(input: {
if (combined.includes("entity discovery") || combined.includes("entity_resolution")) { if (combined.includes("entity discovery") || combined.includes("entity_resolution")) {
return "entity_grounding"; return "entity_grounding";
} }
if (
combined.includes("broad_business_evaluation") ||
combined.includes("broad_evaluation") ||
combined.includes("business overview") ||
combined.includes("business_overview") ||
combined.includes("company analysis") ||
combined.includes("business audit")
) {
return "business_overview";
}
if ( if (
combined.includes("inventory") || combined.includes("inventory") ||
combined.includes("stock") || combined.includes("stock") ||
@ -174,6 +184,9 @@ function timeScopeNeedFor(input: {
if (input.family === "activity_lifecycle") { if (input.family === "activity_lifecycle") {
return "open_activity_window"; return "open_activity_window";
} }
if (input.family === "business_overview") {
return input.explicitDateScope ? "explicit_period" : "all_time_scope";
}
if (input.family === "inventory_stock_snapshot" || input.family === "inventory_supplier_overlap") { if (input.family === "inventory_stock_snapshot" || input.family === "inventory_supplier_overlap") {
return input.explicitDateScope ? "explicit_period" : "as_of_date_required"; return input.explicitDateScope ? "explicit_period" : "as_of_date_required";
} }
@ -291,6 +304,9 @@ function proofExpectationFor(input: {
if (input.family === "activity_lifecycle") { if (input.family === "activity_lifecycle") {
return "bounded_inference"; return "bounded_inference";
} }
if (input.family === "business_overview") {
return "bounded_inference";
}
return "coverage_checked_fact"; return "coverage_checked_fact";
} }
@ -370,6 +386,15 @@ function decompositionCandidatesFor(input: {
pushUnique(result, "explain_evidence_basis"); pushUnique(result, "explain_evidence_basis");
return result; return result;
} }
if (input.family === "business_overview") {
pushUnique(result, "collect_scoped_movements");
pushUnique(result, "aggregate_checked_amounts");
pushUnique(result, "aggregate_ranked_axis_values");
pushUnique(result, "fetch_supporting_documents");
pushUnique(result, "probe_coverage");
pushUnique(result, "explain_evidence_basis");
return result;
}
if (input.family === "inventory_stock_snapshot") { if (input.family === "inventory_stock_snapshot") {
pushUnique(result, "fetch_scoped_movements"); pushUnique(result, "fetch_scoped_movements");
pushUnique(result, "aggregate_checked_amounts"); pushUnique(result, "aggregate_checked_amounts");
@ -407,6 +432,11 @@ function forbiddenOverclaimFlagsFor(family: string | null): string[] {
if (family === "activity_lifecycle") { if (family === "activity_lifecycle") {
pushUnique(result, "no_legal_age_claim_without_evidence"); pushUnique(result, "no_legal_age_claim_without_evidence");
} }
if (family === "business_overview") {
pushUnique(result, "no_unchecked_fact_totals");
pushUnique(result, "no_unchecked_business_health_claim");
pushUnique(result, "no_profit_or_margin_claim_without_evidence");
}
if (family === "value_flow" || family === "movement_evidence" || family === "document_evidence") { if (family === "value_flow" || family === "movement_evidence" || family === "document_evidence") {
pushUnique(result, "no_unchecked_fact_totals"); pushUnique(result, "no_unchecked_fact_totals");
} }
@ -487,9 +517,16 @@ export function buildAssistantMcpDiscoveryDataNeedGraph(
!explicitOrganizationScope !explicitOrganizationScope
) { ) {
pushUnique(clarificationGaps, "organization"); pushUnique(clarificationGaps, "organization");
} else if (
subjectCandidates.length === 0 &&
businessFactFamily === "business_overview" &&
!explicitOrganizationScope
) {
pushUnique(clarificationGaps, "organization");
} else if ( } else if (
subjectCandidates.length === 0 && subjectCandidates.length === 0 &&
businessFactFamily !== "schema_surface" && businessFactFamily !== "schema_surface" &&
businessFactFamily !== "business_overview" &&
!openScopeWithoutSubject && !openScopeWithoutSubject &&
!metadataScopedOpenLaneWithoutSubject && !metadataScopedOpenLaneWithoutSubject &&
!inventoryStockSnapshotWithoutSubject !inventoryStockSnapshotWithoutSubject
@ -541,6 +578,9 @@ export function buildAssistantMcpDiscoveryDataNeedGraph(
if (allTimeScopeHint) { if (allTimeScopeHint) {
pushReason(reasonCodes, "data_need_graph_all_time_scope_hint"); pushReason(reasonCodes, "data_need_graph_all_time_scope_hint");
} }
if (businessFactFamily === "business_overview" && !explicitDateScope) {
pushReason(reasonCodes, "data_need_graph_business_overview_defaults_to_all_time_scope");
}
if (clarificationGaps.includes("organization")) { if (clarificationGaps.includes("organization")) {
pushReason(reasonCodes, "data_need_graph_open_scope_total_needs_organization"); pushReason(reasonCodes, "data_need_graph_open_scope_total_needs_organization");
} }

View File

@ -200,6 +200,7 @@ export type AssistantMcpDiscoveryPilotScope =
| "counterparty_value_flow_query_movements_v1" | "counterparty_value_flow_query_movements_v1"
| "counterparty_supplier_payout_query_movements_v1" | "counterparty_supplier_payout_query_movements_v1"
| "counterparty_bidirectional_value_flow_query_movements_v1" | "counterparty_bidirectional_value_flow_query_movements_v1"
| "business_overview_route_template_v1"
| "inventory_route_template_v1"; | "inventory_route_template_v1";
export interface AssistantMcpDiscoveryPilotExecutionContract { export interface AssistantMcpDiscoveryPilotExecutionContract {
@ -2713,6 +2714,8 @@ function pilotScopeForPlanner(planner: AssistantMcpDiscoveryPlannerContract): As
case "value_flow_ranking": case "value_flow_ranking":
case "value_flow": case "value_flow":
return valueFlowPilotProfile(planner).scope; return valueFlowPilotProfile(planner).scope;
case "business_overview":
return "business_overview_route_template_v1";
case "document_evidence": case "document_evidence":
return "counterparty_document_evidence_query_documents_v1"; return "counterparty_document_evidence_query_documents_v1";
case "lifecycle": case "lifecycle":

View File

@ -66,6 +66,7 @@ export type AssistantMcpDiscoveryChainId =
| "value_flow_comparison" | "value_flow_comparison"
| "value_flow_ranking" | "value_flow_ranking"
| "lifecycle" | "lifecycle"
| "business_overview"
| "movement_evidence" | "movement_evidence"
| "document_evidence" | "document_evidence"
| "entity_resolution"; | "entity_resolution";
@ -922,6 +923,32 @@ function recipeFor(input: AssistantMcpDiscoveryPlannerInput): PlannerRecipe {
}); });
} }
if (graphFactFamily === "business_overview") {
pushUnique(axes, "organization");
pushUnique(axes, "aggregate_axis");
pushUnique(axes, "amount");
pushUnique(axes, "coverage_target");
pushUnique(axes, "evidence_basis");
pushUnique(axes, "profit_margin_boundary");
const template = getAssistantMcpCatalogChainTemplate("business_overview");
const primitiveSelection = selectPrimitivesFromGraphAndCatalog({
dataNeedGraph,
fallbackPrimitives: template.fallback_primitives,
requiredAxes: axes,
metadataSurface: input.metadataSurface,
actionFamily: action || graphAction,
allowAggregateByAxis: true,
selectedChainId: "business_overview"
});
return recipeFromCatalogChainTemplate({
chainId: "business_overview",
axes,
primitives: primitiveSelection.primitives,
reason: "planner_selected_business_overview_from_data_need_graph",
extraReasons: primitiveSelection.reasonCodes
});
}
if (graphFactFamily === "activity_lifecycle") { if (graphFactFamily === "activity_lifecycle") {
pushUnique(axes, "document_date"); pushUnique(axes, "document_date");
pushUnique(axes, "coverage_target"); pushUnique(axes, "coverage_target");

View File

@ -42,7 +42,8 @@ describe("assistant MCP catalog index", () => {
"value_flow", "value_flow",
"value_flow_comparison", "value_flow_comparison",
"value_flow_ranking", "value_flow_ranking",
"lifecycle" "lifecycle",
"business_overview"
]); ]);
for (const template of index.chain_templates) { for (const template of index.chain_templates) {
expect(template.safe_for_model_planning).toBe(true); expect(template.safe_for_model_planning).toBe(true);
@ -63,6 +64,7 @@ describe("assistant MCP catalog index", () => {
const valueFlowComparisonTemplate = getAssistantMcpCatalogChainTemplate("value_flow_comparison"); const valueFlowComparisonTemplate = getAssistantMcpCatalogChainTemplate("value_flow_comparison");
const valueFlowRankingTemplate = getAssistantMcpCatalogChainTemplate("value_flow_ranking"); const valueFlowRankingTemplate = getAssistantMcpCatalogChainTemplate("value_flow_ranking");
const lifecycleTemplate = getAssistantMcpCatalogChainTemplate("lifecycle"); const lifecycleTemplate = getAssistantMcpCatalogChainTemplate("lifecycle");
const businessOverviewTemplate = getAssistantMcpCatalogChainTemplate("business_overview");
const inventorySnapshotTemplate = getAssistantMcpCatalogChainTemplate("inventory_stock_snapshot"); const inventorySnapshotTemplate = getAssistantMcpCatalogChainTemplate("inventory_stock_snapshot");
const inventoryProvenanceTemplate = getAssistantMcpCatalogChainTemplate("inventory_purchase_provenance"); const inventoryProvenanceTemplate = getAssistantMcpCatalogChainTemplate("inventory_purchase_provenance");
const inventorySaleTraceTemplate = getAssistantMcpCatalogChainTemplate("inventory_sale_trace"); const inventorySaleTraceTemplate = getAssistantMcpCatalogChainTemplate("inventory_sale_trace");
@ -94,6 +96,19 @@ describe("assistant MCP catalog index", () => {
expect(lifecycleTemplate.planning_tags).toEqual( expect(lifecycleTemplate.planning_tags).toEqual(
expect.arrayContaining(["bounded_inference", "activity_window", "legal_fact_boundary"]) expect.arrayContaining(["bounded_inference", "activity_window", "legal_fact_boundary"])
); );
expect(businessOverviewTemplate.fallback_primitives).toEqual([
"query_movements",
"aggregate_by_axis",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
]);
expect(businessOverviewTemplate.base_required_axes).toEqual(
expect.arrayContaining(["organization", "aggregate_axis", "coverage_target", "profit_margin_boundary"])
);
expect(businessOverviewTemplate.planning_tags).toEqual(
expect.arrayContaining(["business_overview", "bounded_inference", "explanation"])
);
expect(inventorySnapshotTemplate.base_required_axes).toEqual( expect(inventorySnapshotTemplate.base_required_axes).toEqual(
expect.arrayContaining(["as_of_date", "warehouse", "aggregate_axis", "quantity", "coverage_target"]) expect.arrayContaining(["as_of_date", "warehouse", "aggregate_axis", "quantity", "coverage_target"])
); );
@ -170,10 +185,35 @@ describe("assistant MCP catalog index", () => {
ranking_need: "top_desc", ranking_need: "top_desc",
required_axes: ["organization", "period", "aggregate_axis", "amount", "coverage_target"] required_axes: ["organization", "period", "aggregate_axis", "amount", "coverage_target"]
}); });
const businessOverviewTemplates = searchAssistantMcpCatalogChainTemplatesByFactAxis({
business_fact_family: "business_overview",
action_family: "broad_evaluation",
required_axes: ["organization", "all_time_scope", "aggregate_axis", "amount", "coverage_target", "evidence_basis"]
});
expect(documentTemplates[0]).toBe("document_evidence"); expect(documentTemplates[0]).toBe("document_evidence");
expect(comparisonTemplates[0]).toBe("value_flow_comparison"); expect(comparisonTemplates[0]).toBe("value_flow_comparison");
expect(rankingTemplates[0]).toBe("value_flow_ranking"); expect(rankingTemplates[0]).toBe("value_flow_ranking");
expect(businessOverviewTemplates[0]).toBe("business_overview");
});
it("can search reviewed primitives for bounded business overview chains", () => {
const primitives = searchAssistantMcpCatalogPrimitivesByFactAxis({
business_fact_family: "business_overview",
action_family: "broad_evaluation",
required_axes: ["organization", "all_time_scope", "aggregate_axis", "amount", "coverage_target", "evidence_basis"]
});
expect(primitives).toEqual(
expect.arrayContaining([
"query_movements",
"aggregate_by_axis",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
])
);
expect(primitives).not.toContain("search_business_entity");
}); });
it("can search reviewed primitives for inventory stock snapshot chains", () => { it("can search reviewed primitives for inventory stock snapshot chains", () => {

View File

@ -71,6 +71,56 @@ describe("assistant MCP discovery data need graph", () => {
expect(result.forbidden_overclaim_flags).toContain("no_unresolved_entity_claim"); expect(result.forbidden_overclaim_flags).toContain("no_unresolved_entity_claim");
}); });
it("models broad business evaluation as a bounded business-overview evidence graph", () => {
const result = buildAssistantMcpDiscoveryDataNeedGraph({
semanticDataNeed: "business overview evidence with bounded analyst interpretation",
rawUtterance: "дай полный анализ компании и LLM-аудит бизнеса",
turnMeaning: {
asked_domain_family: "business_overview",
asked_action_family: "broad_evaluation",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
expect(result.business_fact_family).toBe("business_overview");
expect(result.action_family).toBe("broad_evaluation");
expect(result.time_scope_need).toBe("all_time_scope");
expect(result.proof_expectation).toBe("bounded_inference");
expect(result.clarification_gaps).toEqual([]);
expect(result.decomposition_candidates).toEqual([
"collect_scoped_movements",
"aggregate_checked_amounts",
"aggregate_ranked_axis_values",
"fetch_supporting_documents",
"probe_coverage",
"explain_evidence_basis"
]);
expect(result.forbidden_overclaim_flags).toEqual(
expect.arrayContaining([
"no_unchecked_business_health_claim",
"no_profit_or_margin_claim_without_evidence"
])
);
expect(result.reason_codes).toContain("data_need_graph_family_business_overview");
expect(result.reason_codes).toContain("data_need_graph_business_overview_defaults_to_all_time_scope");
});
it("requires organization scope before a fresh broad business overview probe", () => {
const result = buildAssistantMcpDiscoveryDataNeedGraph({
semanticDataNeed: "business overview evidence with bounded analyst interpretation",
rawUtterance: "как оценишь деятельность компании?",
turnMeaning: {
asked_domain_family: "business_overview",
asked_action_family: "broad_evaluation",
unsupported_but_understood_family: "broad_business_evaluation"
}
});
expect(result.business_fact_family).toBe("business_overview");
expect(result.clarification_gaps).toEqual(["organization"]);
expect(result.proof_expectation).toBe("clarification_required");
});
it("builds a subjectless inventory stock snapshot graph with an as-of date gate", () => { it("builds a subjectless inventory stock snapshot graph with an as-of date gate", () => {
const result = buildAssistantMcpDiscoveryDataNeedGraph({ const result = buildAssistantMcpDiscoveryDataNeedGraph({
semanticDataNeed: "inventory stock snapshot evidence", semanticDataNeed: "inventory stock snapshot evidence",

View File

@ -103,6 +103,57 @@ describe("assistant MCP discovery pilot executor", () => {
expect(deps.executeAddressMcpQuery).not.toHaveBeenCalled(); expect(deps.executeAddressMcpQuery).not.toHaveBeenCalled();
}); });
it("keeps business overview as an explicit unsupported runtime scope until the fresh multi-probe bridge exists", async () => {
const planner = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "business_overview",
action_family: "broad_evaluation",
aggregation_need: null,
time_scope_need: "all_time_scope",
comparison_need: null,
ranking_need: null,
proof_expectation: "bounded_inference",
clarification_gaps: [],
decomposition_candidates: [
"collect_scoped_movements",
"aggregate_checked_amounts",
"aggregate_ranked_axis_values",
"fetch_supporting_documents",
"probe_coverage",
"explain_evidence_basis"
],
forbidden_overclaim_flags: ["no_raw_model_claims", "no_profit_or_margin_claim_without_evidence"],
reason_codes: ["data_need_graph_built", "data_need_graph_family_business_overview"]
},
turnMeaning: {
asked_domain_family: "business_overview",
asked_action_family: "broad_evaluation",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
const deps = buildDeps([]);
const result = await executeAssistantMcpDiscoveryPilot(planner, deps);
expect(planner.planner_status).toBe("ready_for_execution");
expect(result.pilot_status).toBe("unsupported");
expect(result.pilot_scope).toBe("business_overview_route_template_v1");
expect(result.mcp_execution_performed).toBe(false);
expect(result.executed_primitives).toEqual([]);
expect(result.skipped_primitives).toEqual([
"query_movements",
"aggregate_by_axis",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
]);
expect(result.reason_codes).toContain("pilot_scope_unsupported_for_live_execution");
expect(deps.executeAddressMcpQuery).not.toHaveBeenCalled();
});
it("uses the explicit selected chain id when choosing the movement pilot scope", async () => { it("uses the explicit selected chain id when choosing the movement pilot scope", async () => {
const planner = planAssistantMcpDiscovery({ const planner = planAssistantMcpDiscovery({
turnMeaning: { turnMeaning: {

View File

@ -184,6 +184,18 @@ describe("assistant MCP discovery planner", () => {
} }
} }
}, },
{
name: "business_overview",
expected: "business_overview",
input: {
dataNeedGraph: graph("business_overview", "broad_evaluation", { subject_candidates: [] }),
turnMeaning: {
asked_action_family: "broad_evaluation",
explicit_organization_scope: "Org",
explicit_date_scope: "2020"
}
}
},
{ {
name: "inventory_stock_snapshot", name: "inventory_stock_snapshot",
expected: "inventory_stock_snapshot", expected: "inventory_stock_snapshot",
@ -209,6 +221,73 @@ describe("assistant MCP discovery planner", () => {
} }
}); });
it("builds a catalog-compatible business overview plan without pretending the fresh runtime probe exists yet", () => {
const result = planAssistantMcpDiscovery({
dataNeedGraph: {
schema_version: "assistant_data_need_graph_v1",
policy_owner: "assistantMcpDiscoveryDataNeedGraph",
subject_candidates: [],
business_fact_family: "business_overview",
action_family: "broad_evaluation",
aggregation_need: null,
time_scope_need: "all_time_scope",
comparison_need: null,
ranking_need: null,
proof_expectation: "bounded_inference",
clarification_gaps: [],
decomposition_candidates: [
"collect_scoped_movements",
"aggregate_checked_amounts",
"aggregate_ranked_axis_values",
"fetch_supporting_documents",
"probe_coverage",
"explain_evidence_basis"
],
forbidden_overclaim_flags: [
"no_raw_model_claims",
"no_unchecked_business_health_claim",
"no_profit_or_margin_claim_without_evidence"
],
reason_codes: ["data_need_graph_built", "data_need_graph_family_business_overview"]
},
turnMeaning: {
asked_domain_family: "business_overview",
asked_action_family: "broad_evaluation",
explicit_organization_scope: "ООО Альтернатива Плюс"
}
});
expect(result.planner_status).toBe("ready_for_execution");
expect(result.selected_chain_id).toBe("business_overview");
expect(result.semantic_data_need).toBe("business overview evidence with bounded analyst interpretation");
expect(result.proposed_primitives).toEqual([
"query_movements",
"aggregate_by_axis",
"query_documents",
"probe_coverage",
"explain_evidence_basis"
]);
expect(result.required_axes).toEqual([
"organization",
"all_time_scope",
"aggregate_axis",
"amount",
"coverage_target",
"evidence_basis",
"profit_margin_boundary"
]);
expect(result.catalog_chain_template_matches[0]).toBe("business_overview");
expect(result.catalog_chain_template_alignment).toMatchObject({
alignment_status: "selected_matches_top",
top_chain_template_match: "business_overview",
selected_chain_template_rank: 1,
selected_chain_matches_top: true
});
expect(result.catalog_review.review_status).toBe("catalog_compatible");
expect(result.reason_codes).toContain("planner_selected_business_overview_from_data_need_graph");
expect(result.reason_codes).toContain("planner_instantiated_catalog_chain_template_business_overview");
});
it("keeps bidirectional value-flow comparison executable when checked totals are derived without aggregate_by_axis", () => { it("keeps bidirectional value-flow comparison executable when checked totals are derived without aggregate_by_axis", () => {
const result = planAssistantMcpDiscovery({ const result = planAssistantMcpDiscovery({
dataNeedGraph: { dataNeedGraph: {

View File

@ -134,7 +134,8 @@ describe("assistant MCP discovery runtime entry point", () => {
asked_action_family: "inspect_fields" asked_action_family: "inspect_fields"
}); });
expect(result.bridge?.pilot.pilot_scope).toBe("metadata_inspection_v1"); expect(result.bridge?.pilot.pilot_scope).toBe("metadata_inspection_v1");
expect(result.bridge?.answer_draft.headline).toContain("метаданным 1С"); expect(result.bridge?.answer_draft.headline).toContain("схеме 1С");
expect(result.bridge?.answer_draft.headline).toContain("подходящие объекты");
}); });
it("runs the bridge for raw entity-resolution wording and executes the full grounding chain", async () => { it("runs the bridge for raw entity-resolution wording and executes the full grounding chain", async () => {