АРЧ АП11 - Архитектура после регресса: Архитектура: протянуть shared organization authority в transition carryover и удержать phase12 replay зелёным
This commit is contained in:
parent
0ecee2b360
commit
4e1830282b
|
|
@ -325,10 +325,16 @@ Still open after the accepted phase12 replay:
|
||||||
- root supplier tails anomaly questions re-enter `hybrid_store_plus_live` with grounded fragments and non-empty deterministic route summaries;
|
- root supplier tails anomaly questions re-enter `hybrid_store_plus_live` with grounded fragments and non-empty deterministic route summaries;
|
||||||
- narrowing follow-up for `2020-06 / account 60` now keeps hybrid/batch routing instead of collapsing into empty clarification;
|
- narrowing follow-up for `2020-06 / account 60` now keeps hybrid/batch routing instead of collapsing into empty clarification;
|
||||||
- the broader hybrid investigation contour is therefore back under explicit runtime authority rather than ambient luck.
|
- the broader hybrid investigation contour is therefore back under explicit runtime authority rather than ambient luck.
|
||||||
- the remaining translit root seam is now also closed in the same contour:
|
- the remaining translit root seam is now also closed in the same contour:
|
||||||
- transliterated supplier-tail wording no longer loses the causal tail during predecompose entry handling;
|
- transliterated supplier-tail wording no longer loses the causal tail during predecompose entry handling;
|
||||||
- live replay `address_truth_harness_phase13_hybrid_followup_authority_live_20260418_rerun4` is accepted with the translit root step returning `factual_with_explanation` and staying inside hybrid investigation routing;
|
- live replay `address_truth_harness_phase13_hybrid_followup_authority_live_20260418_rerun4` is accepted with the translit root step returning `factual_with_explanation` and staying inside hybrid investigation routing;
|
||||||
- endpoint coverage now explicitly requires the translit account-60 tail question to keep every routed fragment in `hybrid_store_plus_live`, so future refactors cannot silently split the same question back into `hybrid + store_canonical`.
|
- endpoint coverage now explicitly requires the translit account-60 tail question to keep every routed fragment in `hybrid_store_plus_live`, so future refactors cannot silently split the same question back into `hybrid + store_canonical`.
|
||||||
|
- the next authority-convergence pass now removes one more local organization reconstruction seam from the transition hot path:
|
||||||
|
- `assistantTransitionPolicy` no longer reconstructs clarification/company authority only from ad hoc history scans and raw continuity snapshot pieces;
|
||||||
|
- follow-up carryover now reads the shared organization authority object first, including assistant-side active organization memory and clarification candidates, before falling back to older local filters;
|
||||||
|
- this matters because mixed follow-up questions that pivot after assistant-side company fixation no longer depend on whether the previous address debug happened to still carry `organization` in its own extracted filters;
|
||||||
|
- targeted transition regression now protects the case where grounded history is empty but assistant-side organization authority is already present;
|
||||||
|
- wide saved-session replay `address_truth_harness_phase12_wider_saved_session_pool_live_20260418_rerun5` remains accepted `20/20`, which is the critical proof that this transition-layer convergence did not reopen the broader continuity path.
|
||||||
|
|
||||||
## Next Execution Slice (2026-04-18)
|
## Next Execution Slice (2026-04-18)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -331,18 +331,23 @@ function createAssistantTransitionPolicy(deps) {
|
||||||
? latestAddressItem
|
? latestAddressItem
|
||||||
: findRecentUsableAddressAssistantItem(items)) ?? latestAddressItem;
|
: findRecentUsableAddressAssistantItem(items)) ?? latestAddressItem;
|
||||||
const previousAddressDebug = previousAddressItem?.debug ?? null;
|
const previousAddressDebug = previousAddressItem?.debug ?? null;
|
||||||
const continuitySnapshot = (0, assistantContinuityPolicy_1.resolveAssistantContinuitySnapshot)({
|
|
||||||
sessionItems: items,
|
|
||||||
toNonEmptyString: deps.toNonEmptyString
|
|
||||||
});
|
|
||||||
const lastOrganizationClarificationDebug = deps.findLastOrganizationClarificationAddressDebug(items);
|
const lastOrganizationClarificationDebug = deps.findLastOrganizationClarificationAddressDebug(items);
|
||||||
const organizationClarificationCandidates = Array.isArray(lastOrganizationClarificationDebug?.organization_candidates)
|
const organizationAuthority = (0, assistantContinuityPolicy_1.resolveAssistantOrganizationAuthority)({
|
||||||
? deps.mergeKnownOrganizations(lastOrganizationClarificationDebug.organization_candidates)
|
sessionItems: items,
|
||||||
|
lastOrganizationClarificationDebug,
|
||||||
|
toNonEmptyString: deps.toNonEmptyString,
|
||||||
|
normalizeOrganizationScopeValue: deps.normalizeOrganizationScopeValue,
|
||||||
|
mergeKnownOrganizations: deps.mergeKnownOrganizations
|
||||||
|
});
|
||||||
|
const continuitySnapshot = organizationAuthority.continuitySnapshot;
|
||||||
|
const organizationClarificationCandidates = Array.isArray(organizationAuthority.organizationClarificationCandidates)
|
||||||
|
? organizationAuthority.organizationClarificationCandidates
|
||||||
: [];
|
: [];
|
||||||
const organizationClarificationSelection = deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ??
|
const organizationClarificationSelection = deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ??
|
||||||
(deps.toNonEmptyString(alternateMessage)
|
(deps.toNonEmptyString(alternateMessage)
|
||||||
? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates)
|
? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates)
|
||||||
: null);
|
: null) ??
|
||||||
|
deps.normalizeOrganizationScopeValue(organizationAuthority.organizationClarificationSelectionFromScope);
|
||||||
const hasOrganizationClarificationContinuation = Boolean(lastOrganizationClarificationDebug && organizationClarificationSelection);
|
const hasOrganizationClarificationContinuation = Boolean(lastOrganizationClarificationDebug && organizationClarificationSelection);
|
||||||
const followupOffer = previousAddressDebug ? deps.buildAddressFollowupOffer(previousAddressDebug) : null;
|
const followupOffer = previousAddressDebug ? deps.buildAddressFollowupOffer(previousAddressDebug) : null;
|
||||||
const hasImplicitContinuationSignal = Boolean(previousAddressDebug) &&
|
const hasImplicitContinuationSignal = Boolean(previousAddressDebug) &&
|
||||||
|
|
@ -650,6 +655,11 @@ function createAssistantTransitionPolicy(deps) {
|
||||||
previousFilters.organization = historicalOrganization;
|
previousFilters.organization = historicalOrganization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const authorityActiveOrganization = deps.normalizeOrganizationScopeValue(organizationAuthority.activeOrganization) ??
|
||||||
|
deps.normalizeOrganizationScopeValue(organizationAuthority.continuityActiveOrganization);
|
||||||
|
if (!deps.toNonEmptyString(previousFilters.organization) && authorityActiveOrganization) {
|
||||||
|
previousFilters.organization = authorityActiveOrganization;
|
||||||
|
}
|
||||||
if (!deps.toNonEmptyString(previousFilters.organization) && continuitySnapshot.activeOrganization) {
|
if (!deps.toNonEmptyString(previousFilters.organization) && continuitySnapshot.activeOrganization) {
|
||||||
previousFilters.organization = continuitySnapshot.activeOrganization;
|
previousFilters.organization = continuitySnapshot.activeOrganization;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import {
|
||||||
buildInventoryRootFrameFromAddressDebug,
|
buildInventoryRootFrameFromAddressDebug,
|
||||||
readAddressDebugFilters,
|
readAddressDebugFilters,
|
||||||
readAddressDebugItem,
|
readAddressDebugItem,
|
||||||
resolveAssistantContinuitySnapshot
|
resolveAssistantOrganizationAuthority
|
||||||
} from "./assistantContinuityPolicy";
|
} from "./assistantContinuityPolicy";
|
||||||
|
|
||||||
export function createAssistantTransitionPolicy(deps) {
|
export function createAssistantTransitionPolicy(deps) {
|
||||||
|
|
@ -413,19 +413,24 @@ export function createAssistantTransitionPolicy(deps) {
|
||||||
? latestAddressItem
|
? latestAddressItem
|
||||||
: findRecentUsableAddressAssistantItem(items)) ?? latestAddressItem;
|
: findRecentUsableAddressAssistantItem(items)) ?? latestAddressItem;
|
||||||
const previousAddressDebug = previousAddressItem?.debug ?? null;
|
const previousAddressDebug = previousAddressItem?.debug ?? null;
|
||||||
const continuitySnapshot = resolveAssistantContinuitySnapshot({
|
|
||||||
sessionItems: items,
|
|
||||||
toNonEmptyString: deps.toNonEmptyString
|
|
||||||
});
|
|
||||||
const lastOrganizationClarificationDebug = deps.findLastOrganizationClarificationAddressDebug(items);
|
const lastOrganizationClarificationDebug = deps.findLastOrganizationClarificationAddressDebug(items);
|
||||||
const organizationClarificationCandidates = Array.isArray(lastOrganizationClarificationDebug?.organization_candidates)
|
const organizationAuthority = resolveAssistantOrganizationAuthority({
|
||||||
? deps.mergeKnownOrganizations(lastOrganizationClarificationDebug.organization_candidates)
|
sessionItems: items,
|
||||||
|
lastOrganizationClarificationDebug,
|
||||||
|
toNonEmptyString: deps.toNonEmptyString,
|
||||||
|
normalizeOrganizationScopeValue: deps.normalizeOrganizationScopeValue,
|
||||||
|
mergeKnownOrganizations: deps.mergeKnownOrganizations
|
||||||
|
});
|
||||||
|
const continuitySnapshot = organizationAuthority.continuitySnapshot;
|
||||||
|
const organizationClarificationCandidates = Array.isArray(organizationAuthority.organizationClarificationCandidates)
|
||||||
|
? organizationAuthority.organizationClarificationCandidates
|
||||||
: [];
|
: [];
|
||||||
const organizationClarificationSelection =
|
const organizationClarificationSelection =
|
||||||
deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ??
|
deps.resolveOrganizationSelectionFromMessage(userMessage, organizationClarificationCandidates) ??
|
||||||
(deps.toNonEmptyString(alternateMessage)
|
(deps.toNonEmptyString(alternateMessage)
|
||||||
? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates)
|
? deps.resolveOrganizationSelectionFromMessage(String(alternateMessage ?? ""), organizationClarificationCandidates)
|
||||||
: null);
|
: null) ??
|
||||||
|
deps.normalizeOrganizationScopeValue(organizationAuthority.organizationClarificationSelectionFromScope);
|
||||||
const hasOrganizationClarificationContinuation = Boolean(
|
const hasOrganizationClarificationContinuation = Boolean(
|
||||||
lastOrganizationClarificationDebug && organizationClarificationSelection
|
lastOrganizationClarificationDebug && organizationClarificationSelection
|
||||||
);
|
);
|
||||||
|
|
@ -793,6 +798,12 @@ export function createAssistantTransitionPolicy(deps) {
|
||||||
previousFilters.organization = historicalOrganization;
|
previousFilters.organization = historicalOrganization;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const authorityActiveOrganization =
|
||||||
|
deps.normalizeOrganizationScopeValue(organizationAuthority.activeOrganization) ??
|
||||||
|
deps.normalizeOrganizationScopeValue(organizationAuthority.continuityActiveOrganization);
|
||||||
|
if (!deps.toNonEmptyString(previousFilters.organization) && authorityActiveOrganization) {
|
||||||
|
previousFilters.organization = authorityActiveOrganization;
|
||||||
|
}
|
||||||
if (!deps.toNonEmptyString(previousFilters.organization) && continuitySnapshot.activeOrganization) {
|
if (!deps.toNonEmptyString(previousFilters.organization) && continuitySnapshot.activeOrganization) {
|
||||||
previousFilters.organization = continuitySnapshot.activeOrganization;
|
previousFilters.organization = continuitySnapshot.activeOrganization;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,54 @@ describe("assistantTransitionPolicy", () => {
|
||||||
expect(carryover?.followupContext?.root_context_only).toBeUndefined();
|
expect(carryover?.followupContext?.root_context_only).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("hydrates follow-up organization from shared assistant authority when local history filters are empty", () => {
|
||||||
|
const policy = buildPolicy({
|
||||||
|
findLastAddressAssistantItem: () => ({
|
||||||
|
text: "Подтвержденная дебиторская задолженность на 31.03.2020 собрана.",
|
||||||
|
debug: {
|
||||||
|
detected_intent: "receivables_confirmed_as_of_date",
|
||||||
|
extracted_filters: {
|
||||||
|
as_of_date: "2020-03-31",
|
||||||
|
period_from: "2020-03-01",
|
||||||
|
period_to: "2020-03-31"
|
||||||
|
},
|
||||||
|
anchor_type: "organization",
|
||||||
|
anchor_value_resolved: null
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
hasAddressFollowupContextSignal: () => true,
|
||||||
|
hasReferentialPointer: () => true,
|
||||||
|
findRecentInventoryRootFrame: () => null,
|
||||||
|
findRecentAddressFilterValue: () => null,
|
||||||
|
resolveAddressIntent: () => ({ intent: "unknown" })
|
||||||
|
});
|
||||||
|
|
||||||
|
const carryover = policy.resolveAddressFollowupCarryoverContext(
|
||||||
|
"остатки по складу на эту же дату",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
role: "assistant",
|
||||||
|
text: "Компания уже выбрана в живом чате.",
|
||||||
|
debug: {
|
||||||
|
assistant_active_organization: 'ООО "Альтернатива Плюс"',
|
||||||
|
assistant_known_organizations: ['ООО "Альтернатива Плюс"', 'ООО "Лайт"']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(carryover?.followupContext?.previous_filters).toMatchObject({
|
||||||
|
organization: 'ООО "Альтернатива Плюс"',
|
||||||
|
as_of_date: "2020-03-31",
|
||||||
|
period_from: "2020-03-01",
|
||||||
|
period_to: "2020-03-31"
|
||||||
|
});
|
||||||
|
expect(carryover?.followupContext?.target_intent).toBe("inventory_on_hand_as_of_date");
|
||||||
|
});
|
||||||
|
|
||||||
it("bridges selected-item purchase provenance into a VAT period follow-up", () => {
|
it("bridges selected-item purchase provenance into a VAT period follow-up", () => {
|
||||||
const item = "Рабочая станция универсального специалиста";
|
const item = "Рабочая станция универсального специалиста";
|
||||||
const policy = buildPolicy({
|
const policy = buildPolicy({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue