ARCH: связать phase18 capabilities с runtime contracts

This commit is contained in:
dctouch 2026-04-20 07:45:57 +03:00
parent 43d50e21cc
commit 399e29f4a4
9 changed files with 191 additions and 0 deletions

View File

@ -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:

View File

@ -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",

View File

@ -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,

View File

@ -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",

View File

@ -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,

View File

@ -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",

View File

@ -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");

View File

@ -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: {

View File

@ -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: {