feat(confidence-engine): accept episode evidence at graph application
This commit is contained in:
+27
-13
@@ -3971,9 +3971,11 @@ export async function applyValidatedProposal({
|
||||
proposal,
|
||||
previousQuestion = null,
|
||||
answer = null,
|
||||
evidenceContext = null,
|
||||
provider = null,
|
||||
modelName = null,
|
||||
}) {
|
||||
const isLegacySingleTurn = !evidenceContext;
|
||||
const graphValidation = situationGraphSchema.safeParse(situationGraph);
|
||||
const proposalValidation = graphUpdateSchema.safeParse(proposal);
|
||||
|
||||
@@ -4030,11 +4032,15 @@ export async function applyValidatedProposal({
|
||||
);
|
||||
|
||||
// ── 60B.80 — normalise terminal parent closure without explicit confirmation
|
||||
const ownershipChanges = reconcileDecisionClosureOwnership(
|
||||
situationGraph,
|
||||
reconciledProposal.proposal,
|
||||
answer,
|
||||
);
|
||||
// legacy only: episode evidence does not supply a single-answer confirmation string;
|
||||
// Done and Finding agree are NOT closure authority (settled architecture rule).
|
||||
const ownershipChanges = isLegacySingleTurn
|
||||
? reconcileDecisionClosureOwnership(
|
||||
situationGraph,
|
||||
reconciledProposal.proposal,
|
||||
answer,
|
||||
)
|
||||
: { strippedUpdates: [], strippedResolvedIds: [] };
|
||||
if (ownershipChanges.strippedResolvedIds.length > 0) {
|
||||
// Reconciler may have added selectedQuestion = null because the parent
|
||||
// appeared resolved during reconciliation. If we stripped it, restore
|
||||
@@ -4130,12 +4136,16 @@ export async function applyValidatedProposal({
|
||||
validatedProposal,
|
||||
);
|
||||
proposalCompatibilityErrors.push(...selectedQuestionValidation.errors);
|
||||
proposalCompatibilityErrors.push(
|
||||
...validateAnswerMeaningCompatibilityWithRawAnswer({
|
||||
answer,
|
||||
proposal: validatedProposal,
|
||||
}),
|
||||
);
|
||||
// legacy only: raw-answer fidelity is a single-turn safeguard.
|
||||
// Episode evidence carries structured turns — no synthetic answer is constructed.
|
||||
if (isLegacySingleTurn) {
|
||||
proposalCompatibilityErrors.push(
|
||||
...validateAnswerMeaningCompatibilityWithRawAnswer({
|
||||
answer,
|
||||
proposal: validatedProposal,
|
||||
}),
|
||||
);
|
||||
}
|
||||
proposalCompatibilityErrors.push(
|
||||
...validateAnswerMeaningAlignment(validatedProposal),
|
||||
);
|
||||
@@ -4165,10 +4175,14 @@ export async function applyValidatedProposal({
|
||||
? findNodeById(graphSnapshot, previousActiveUnknownNodeId)
|
||||
: null;
|
||||
const affectedNodeIds = buildAffectedNodeIds(graphSnapshot, proposalSnapshot);
|
||||
// For episode evidence: extract turn text from the ordered Q/A sequence.
|
||||
const _epTurns = evidenceContext?.isCompletedEpisode ? evidenceContext.episodeEvidence.turns : null;
|
||||
const _derivedQuestion = isLegacySingleTurn ? previousQuestion : (_epTurns?.[0]?.question ?? "");
|
||||
const _derivedAnswer = isLegacySingleTurn ? answer : (_epTurns?.[0]?.answer ?? "");
|
||||
const reasoningResolution = deriveReasoningStateOverride({
|
||||
graph: graphSnapshot,
|
||||
previousQuestion,
|
||||
answer,
|
||||
previousQuestion: _derivedQuestion,
|
||||
answer: _derivedAnswer,
|
||||
resolvedUnknownNodeIds: validatedProposal.resolvedUnknownNodeIds,
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user