fix(confidence-engine): allow no-op episode reconsideration
This commit is contained in:
@@ -4089,7 +4089,16 @@ export async function applyValidatedProposal({
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!proposalGraphValidation.valid) {
|
if (!proposalGraphValidation.valid) {
|
||||||
proposalCompatibilityErrors.push(...proposalGraphValidation.errors);
|
const acceptsCompletedEpisodeNoOp = evidenceContext?.isCompletedEpisode === true;
|
||||||
|
proposalCompatibilityErrors.push(
|
||||||
|
...proposalGraphValidation.errors.filter(
|
||||||
|
(error) =>
|
||||||
|
!(
|
||||||
|
acceptsCompletedEpisodeNoOp &&
|
||||||
|
error === "Update contains no meaningful change"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const existingEdgeIds = new Set(situationGraph.edges.map((edge) => edge.id));
|
const existingEdgeIds = new Set(situationGraph.edges.map((edge) => edge.id));
|
||||||
|
|||||||
@@ -706,10 +706,10 @@ describe("applyValidatedProposal", () => {
|
|||||||
expect(graph).toEqual(originalGraph);
|
expect(graph).toEqual(originalGraph);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("rejects a proposal with no meaningful change", () => {
|
it("rejects a proposal with no meaningful change", async () => {
|
||||||
const { graph } = makeApplicationFixture();
|
const { graph } = makeApplicationFixture();
|
||||||
|
|
||||||
const result = applyValidatedProposal({
|
const result = await applyValidatedProposal({
|
||||||
situationGraph: graph,
|
situationGraph: graph,
|
||||||
proposal: {
|
proposal: {
|
||||||
addedNodes: [],
|
addedNodes: [],
|
||||||
@@ -740,6 +740,68 @@ describe("applyValidatedProposal", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("accepts a completed-episode proposal with no additional graph mutation", async () => {
|
||||||
|
const { graph } = makeApplicationFixture();
|
||||||
|
const originalGraph = JSON.parse(JSON.stringify(graph));
|
||||||
|
const noOpProposal = {
|
||||||
|
addedNodes: [],
|
||||||
|
updatedNodes: [
|
||||||
|
{
|
||||||
|
nodeId: "n-quality-deterioration",
|
||||||
|
previousStatus: null,
|
||||||
|
newStatus: null,
|
||||||
|
previousValue: null,
|
||||||
|
newValue: null,
|
||||||
|
reason: "No further graph change.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
addedEdges: [],
|
||||||
|
removedEdgeIds: [],
|
||||||
|
resolvedUnknownNodeIds: [],
|
||||||
|
affectedNodeIds: [],
|
||||||
|
selectedQuestion: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = await applyValidatedProposal({
|
||||||
|
situationGraph: graph,
|
||||||
|
proposal: noOpProposal,
|
||||||
|
evidenceContext: {
|
||||||
|
isCompletedEpisode: true,
|
||||||
|
episodeEvidence: {
|
||||||
|
turns: [{ question: "What did you find?", answer: "No further change." }],
|
||||||
|
eligibleCanonicalFindings: [{ proposition: "The episode is preserved." }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(result.updatedSituationGraph.nodes).toEqual(originalGraph.nodes);
|
||||||
|
expect(result.updatedSituationGraph.edges).toEqual(originalGraph.edges);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("still rejects an invalid completed-episode proposal", async () => {
|
||||||
|
const { graph } = makeApplicationFixture();
|
||||||
|
|
||||||
|
const result = await applyValidatedProposal({
|
||||||
|
situationGraph: graph,
|
||||||
|
proposal: {
|
||||||
|
addedNodes: [],
|
||||||
|
updatedNodes: [{ nodeId: "missing-node", reason: "Invalid target." }],
|
||||||
|
addedEdges: [],
|
||||||
|
removedEdgeIds: [],
|
||||||
|
resolvedUnknownNodeIds: [],
|
||||||
|
affectedNodeIds: [],
|
||||||
|
selectedQuestion: null,
|
||||||
|
},
|
||||||
|
evidenceContext: { isCompletedEpisode: true, episodeEvidence: { turns: [] } },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result).toMatchObject({ success: false, stage: "proposal_compatibility" });
|
||||||
|
expect(result.errors).toEqual(expect.arrayContaining([
|
||||||
|
expect.stringContaining("Cannot update non-existent node"),
|
||||||
|
]));
|
||||||
|
});
|
||||||
|
|
||||||
it("resolves one unknown and adds consequential unknowns with one selected question", () => {
|
it("resolves one unknown and adds consequential unknowns with one selected question", () => {
|
||||||
const { graph, ids } = makeApplicationFixture();
|
const { graph, ids } = makeApplicationFixture();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user