ARCH: связать phase18 capabilities с runtime contracts
This commit is contained in:
parent
43d50e21cc
commit
399e29f4a4
|
|
@ -474,6 +474,21 @@ Important semantic conclusion:
|
|||
- the turn `какой оборот был свк` now routes to `customer_revenue_and_payments` and opens with direct turnover for `Группа СВК`, not with stale `Чепурнов` documents or a generic top-client ranking;
|
||||
- off-domain living-chat turns after a business answer are accepted when they stay live and do not replay stale business context.
|
||||
|
||||
## Progress Update - 2026-04-20 Contract Binding Cleanup
|
||||
|
||||
The same phase18 replay was rerun after adding runtime contracts for the counterparty document and value-flow capabilities:
|
||||
|
||||
- live replay artifact: `artifacts/domain_runs/address_truth_harness_phase18_contract_binding_rerun`
|
||||
- `final_status`: `accepted`
|
||||
- `steps_passed`: 7/7
|
||||
|
||||
Contract-layer result:
|
||||
|
||||
- `documents_drilldown`: `transition_contract_id=T1`, `capability_binding_status=bound`, no binding violations;
|
||||
- `address_customer_revenue_and_payments`: `transition_contract_id=T1`, `capability_binding_status=bound`, no binding violations.
|
||||
|
||||
This closes the misleading `capability_contract_missing` / `transition_contract_not_resolved` debug gap for the core phase18 path without changing the user-facing answer semantics.
|
||||
|
||||
## Execution Rule
|
||||
|
||||
Do not implement this plan as:
|
||||
|
|
|
|||
|
|
@ -50,6 +50,18 @@
|
|||
"capability_layer": "compute",
|
||||
"capability_route_mode": "exact"
|
||||
},
|
||||
{
|
||||
"intent": "customer_revenue_and_payments",
|
||||
"capability_id": "address_customer_revenue_and_payments",
|
||||
"capability_layer": "compute",
|
||||
"capability_route_mode": "exact"
|
||||
},
|
||||
{
|
||||
"intent": "supplier_payouts_profile",
|
||||
"capability_id": "address_supplier_payouts_profile",
|
||||
"capability_layer": "compute",
|
||||
"capability_route_mode": "exact"
|
||||
},
|
||||
{
|
||||
"intent": "list_documents_by_counterparty",
|
||||
"capability_id": "documents_drilldown",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ const COMPUTE_EXACT_INTENTS = new Set([
|
|||
"inventory_sale_trace_for_item",
|
||||
"inventory_purchase_to_sale_chain",
|
||||
"inventory_aging_by_purchase_date",
|
||||
"customer_revenue_and_payments",
|
||||
"supplier_payouts_profile",
|
||||
"open_contracts_confirmed_as_of_date",
|
||||
"payables_confirmed_as_of_date",
|
||||
"receivables_confirmed_as_of_date",
|
||||
|
|
@ -128,6 +130,14 @@ function resolveCapabilityEnabled(intent) {
|
|||
: "vat_liability_confirmed_tax_period_route_disabled_by_flag"
|
||||
};
|
||||
}
|
||||
if (intent === "customer_revenue_and_payments" || intent === "supplier_payouts_profile") {
|
||||
return {
|
||||
enabled: config_1.FEATURE_ASSISTANT_ROUTE_ADDRESS_GENERIC_V1,
|
||||
reason: config_1.FEATURE_ASSISTANT_ROUTE_ADDRESS_GENERIC_V1
|
||||
? "counterparty_value_flow_route_enabled"
|
||||
: "counterparty_value_flow_route_disabled_by_flag"
|
||||
};
|
||||
}
|
||||
if (intent === "inventory_on_hand_as_of_date") {
|
||||
return {
|
||||
enabled: config_1.FEATURE_ASSISTANT_ROUTE_BALANCE_EXACT_V1,
|
||||
|
|
|
|||
|
|
@ -324,6 +324,39 @@ exports.INVENTORY_CAPABILITY_CONTRACTS = [
|
|||
})
|
||||
];
|
||||
exports.ROOT_EXACT_CAPABILITY_CONTRACTS = [
|
||||
rootExactCapability({
|
||||
capability_id: "documents_drilldown",
|
||||
domainId: "counterparty_documents",
|
||||
intent_ids: ["list_documents_by_counterparty", "list_documents_by_contract"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
optionalAnchors: ["organization", "date_scope", "counterparty", "contract", "document_type"],
|
||||
resultShape: "counterparty_or_contract_document_list",
|
||||
answerObjectShape: "documents_drilldown_list",
|
||||
scenarioFamilies: ["canonical", "colloquial", "short_counterparty_retarget", "followup_date_carryover"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "address_customer_revenue_and_payments",
|
||||
domainId: "counterparty_revenue",
|
||||
intent_ids: ["customer_revenue_and_payments"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
optionalAnchors: ["organization", "date_scope", "counterparty", "contract"],
|
||||
resultShape: "counterparty_revenue_payment_flow",
|
||||
answerObjectShape: "counterparty_revenue_summary",
|
||||
scenarioFamilies: ["canonical", "colloquial", "short_counterparty_retarget", "answer_top_block_matches_current_user_intent"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "address_supplier_payouts_profile",
|
||||
domainId: "counterparty_payouts",
|
||||
intent_ids: ["supplier_payouts_profile"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
optionalAnchors: ["organization", "date_scope", "counterparty", "contract"],
|
||||
resultShape: "supplier_payout_payment_flow",
|
||||
answerObjectShape: "supplier_payout_summary",
|
||||
scenarioFamilies: ["canonical", "colloquial", "short_counterparty_retarget"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_payables_as_of_date",
|
||||
domainId: "counterparty_debt",
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ const COMPUTE_EXACT_INTENTS = new Set<AddressIntent>([
|
|||
"inventory_sale_trace_for_item",
|
||||
"inventory_purchase_to_sale_chain",
|
||||
"inventory_aging_by_purchase_date",
|
||||
"customer_revenue_and_payments",
|
||||
"supplier_payouts_profile",
|
||||
"open_contracts_confirmed_as_of_date",
|
||||
"payables_confirmed_as_of_date",
|
||||
"receivables_confirmed_as_of_date",
|
||||
|
|
@ -154,6 +156,14 @@ function resolveCapabilityEnabled(intent: AddressIntent): { enabled: boolean; re
|
|||
: "vat_liability_confirmed_tax_period_route_disabled_by_flag"
|
||||
};
|
||||
}
|
||||
if (intent === "customer_revenue_and_payments" || intent === "supplier_payouts_profile") {
|
||||
return {
|
||||
enabled: FEATURE_ASSISTANT_ROUTE_ADDRESS_GENERIC_V1,
|
||||
reason: FEATURE_ASSISTANT_ROUTE_ADDRESS_GENERIC_V1
|
||||
? "counterparty_value_flow_route_enabled"
|
||||
: "counterparty_value_flow_route_disabled_by_flag"
|
||||
};
|
||||
}
|
||||
if (intent === "inventory_on_hand_as_of_date") {
|
||||
return {
|
||||
enabled: FEATURE_ASSISTANT_ROUTE_BALANCE_EXACT_V1,
|
||||
|
|
|
|||
|
|
@ -352,6 +352,39 @@ export const INVENTORY_CAPABILITY_CONTRACTS: readonly AssistantCapabilityContrac
|
|||
] as const;
|
||||
|
||||
export const ROOT_EXACT_CAPABILITY_CONTRACTS: readonly AssistantCapabilityContract[] = [
|
||||
rootExactCapability({
|
||||
capability_id: "documents_drilldown",
|
||||
domainId: "counterparty_documents",
|
||||
intent_ids: ["list_documents_by_counterparty", "list_documents_by_contract"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
optionalAnchors: ["organization", "date_scope", "counterparty", "contract", "document_type"],
|
||||
resultShape: "counterparty_or_contract_document_list",
|
||||
answerObjectShape: "documents_drilldown_list",
|
||||
scenarioFamilies: ["canonical", "colloquial", "short_counterparty_retarget", "followup_date_carryover"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "address_customer_revenue_and_payments",
|
||||
domainId: "counterparty_revenue",
|
||||
intent_ids: ["customer_revenue_and_payments"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
optionalAnchors: ["organization", "date_scope", "counterparty", "contract"],
|
||||
resultShape: "counterparty_revenue_payment_flow",
|
||||
answerObjectShape: "counterparty_revenue_summary",
|
||||
scenarioFamilies: ["canonical", "colloquial", "short_counterparty_retarget", "answer_top_block_matches_current_user_intent"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "address_supplier_payouts_profile",
|
||||
domainId: "counterparty_payouts",
|
||||
intent_ids: ["supplier_payouts_profile"],
|
||||
transitions: ["T1", "T2", "T6", "T7"],
|
||||
requiredAnchors: [],
|
||||
optionalAnchors: ["organization", "date_scope", "counterparty", "contract"],
|
||||
resultShape: "supplier_payout_payment_flow",
|
||||
answerObjectShape: "supplier_payout_summary",
|
||||
scenarioFamilies: ["canonical", "colloquial", "short_counterparty_retarget"]
|
||||
}),
|
||||
rootExactCapability({
|
||||
capability_id: "confirmed_payables_as_of_date",
|
||||
domainId: "counterparty_debt",
|
||||
|
|
|
|||
|
|
@ -119,6 +119,20 @@ describe("address capability policy", () => {
|
|||
expect(decision.capability_route_enabled).toBe(true);
|
||||
});
|
||||
|
||||
it("maps counterparty value-flow intents to exact compute capabilities", () => {
|
||||
const revenue = resolveAddressCapabilityRouteDecision("customer_revenue_and_payments");
|
||||
expect(revenue.capability_id).toBe("address_customer_revenue_and_payments");
|
||||
expect(revenue.capability_layer).toBe("compute");
|
||||
expect(revenue.capability_route_mode).toBe("exact");
|
||||
expect(revenue.capability_route_enabled).toBe(true);
|
||||
expect(revenue.capability_route_reason).toBe("counterparty_value_flow_route_enabled");
|
||||
|
||||
const payouts = resolveAddressCapabilityRouteDecision("supplier_payouts_profile");
|
||||
expect(payouts.capability_id).toBe("address_supplier_payouts_profile");
|
||||
expect(payouts.capability_layer).toBe("compute");
|
||||
expect(payouts.capability_route_mode).toBe("exact");
|
||||
});
|
||||
|
||||
it("maps heuristic list intents to heuristic compute route mode", () => {
|
||||
const decision = resolveAddressCapabilityRouteDecision("list_receivables_counterparties");
|
||||
expect(decision.capability_id).toBe("receivables_candidates_list");
|
||||
|
|
|
|||
|
|
@ -76,6 +76,35 @@ describe("assistant capability runtime binding adapter", () => {
|
|||
expect(binding.violations).toEqual([]);
|
||||
});
|
||||
|
||||
it("binds counterparty revenue answers to the phase18 exact contract", () => {
|
||||
const binding = resolveAssistantCapabilityRuntimeBinding({
|
||||
addressDebug: {
|
||||
capability_id: "address_customer_revenue_and_payments",
|
||||
detected_intent: "customer_revenue_and_payments",
|
||||
detected_mode: "address_query",
|
||||
capability_layer: "compute",
|
||||
capability_route_mode: "exact",
|
||||
extracted_filters: {
|
||||
counterparty: "Группа СВК",
|
||||
organization: "ООО Альтернатива Плюс"
|
||||
},
|
||||
rows_matched: 16,
|
||||
route_expectation_status: "matched"
|
||||
},
|
||||
groundingStatus: "grounded",
|
||||
replyType: "factual"
|
||||
});
|
||||
|
||||
expect(binding.binding_status).toBe("bound");
|
||||
expect(binding.binding_action).toBe("allow");
|
||||
expect(binding.capability_contract_id).toBe("address_customer_revenue_and_payments");
|
||||
expect(binding.transition_id).toBe("T1");
|
||||
expect(binding.transition_allowed).toBe(true);
|
||||
expect(binding.result_shape).toBe("counterparty_revenue_payment_flow");
|
||||
expect(binding.provided_anchors).toEqual(expect.arrayContaining(["counterparty", "organization"]));
|
||||
expect(binding.violations).toEqual([]);
|
||||
});
|
||||
|
||||
it("blocks selected-object capabilities when required anchors are missing", () => {
|
||||
const binding = resolveAssistantCapabilityRuntimeBinding({
|
||||
addressDebug: {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,20 @@ describe("assistant runtime contract registry", () => {
|
|||
expect(contract?.execution_adapter).toBe("AddressQueryService");
|
||||
});
|
||||
|
||||
it("declares counterparty document and value-flow contracts used by semantic dialog authority replay", () => {
|
||||
const documents = getAssistantCapabilityContractByIntent("list_documents_by_counterparty");
|
||||
expect(documents?.capability_id).toBe("documents_drilldown");
|
||||
expect(documents?.supported_transition_classes).toEqual(["T1", "T2", "T6", "T7"]);
|
||||
expect(documents?.result_shape).toBe("counterparty_or_contract_document_list");
|
||||
|
||||
const revenue = getAssistantCapabilityContractByIntent("customer_revenue_and_payments");
|
||||
expect(revenue?.capability_id).toBe("address_customer_revenue_and_payments");
|
||||
expect(revenue?.runtime_lane).toBe("address_exact");
|
||||
expect(revenue?.requires_focus_object).toBe(false);
|
||||
expect(revenue?.supported_transition_classes).toEqual(["T1", "T2", "T6", "T7"]);
|
||||
expect(revenue?.required_scenario_families).toContain("answer_top_block_matches_current_user_intent");
|
||||
});
|
||||
|
||||
it("keeps truth semantics outside answer wording for every pilot inventory capability", () => {
|
||||
for (const contract of listInventoryCapabilityContracts()) {
|
||||
expect(contract.coverage_gate_behavior).toBe("partial_or_blocked_if_evidence_insufficient");
|
||||
|
|
@ -130,6 +144,27 @@ describe("assistant runtime contract registry", () => {
|
|||
expect(decision.carryover_eligibility).toBe("object_only");
|
||||
});
|
||||
|
||||
it("resolves phase18 counterparty revenue shadow as a root exact contract", () => {
|
||||
const decision = resolveAssistantRuntimeContractShadow({
|
||||
addressDebug: {
|
||||
capability_id: "address_customer_revenue_and_payments",
|
||||
detected_intent: "customer_revenue_and_payments",
|
||||
detected_mode: "address_query",
|
||||
capability_layer: "compute",
|
||||
capability_route_mode: "exact",
|
||||
rows_matched: 16,
|
||||
route_expectation_status: "matched"
|
||||
},
|
||||
groundingStatus: "grounded"
|
||||
});
|
||||
|
||||
expect(decision.transition_contract_id).toBe("T1");
|
||||
expect(decision.capability_contract_id).toBe("address_customer_revenue_and_payments");
|
||||
expect(decision.capability_contract_reason).toEqual(["debug_capability_id_matched_contract"]);
|
||||
expect(decision.truth_gate_contract_status).toBe("full_confirmed");
|
||||
expect(decision.carryover_eligibility).toBe("root_only");
|
||||
});
|
||||
|
||||
it("resolves meta follow-up and blocked route expectation in shadow mode", () => {
|
||||
const metaDecision = resolveAssistantRuntimeContractShadow({
|
||||
addressRuntimeMeta: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue