reasoning: ground unclassified answers without category expansion
This commit is contained in:
@@ -2804,6 +2804,16 @@ function proposalResolutionSummary(proposal) {
|
|||||||
return { resolved, proposalText };
|
return { resolved, proposalText };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolvedProposalMeaningText(proposal) {
|
||||||
|
return normaliseSemanticText(
|
||||||
|
(proposal.updatedNodes || [])
|
||||||
|
.filter((update) => update.newStatus === "resolved")
|
||||||
|
.map((update) => update.newValue)
|
||||||
|
.filter((value) => typeof value === "string" && value.trim().length > 0)
|
||||||
|
.join(" "),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function mentionsHardConstraint(text) {
|
function mentionsHardConstraint(text) {
|
||||||
return (
|
return (
|
||||||
text.includes("hard constraint") ||
|
text.includes("hard constraint") ||
|
||||||
@@ -3040,13 +3050,18 @@ function validateAnswerMeaningAlignment(proposal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (supportCategory === "other") {
|
if (supportCategory === "other") {
|
||||||
|
const resolvedMeaningText = resolvedProposalMeaningText(proposal);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
resolved &&
|
resolved &&
|
||||||
containsConstraintBoundaryLanguage(proposalText) &&
|
resolvedMeaningText &&
|
||||||
!containsConstraintBoundaryLanguage(meaningText)
|
!rawAnswerSupportsUnclassifiedMeaning(
|
||||||
|
proposal.answerMeaning.userSupportedMeaning,
|
||||||
|
resolvedMeaningText,
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
errors.push(
|
errors.push(
|
||||||
"Proposal cannot resolve beyond an unclassified answer by introducing an unsupported constraint or preference/trade-off distinction.",
|
"Proposal cannot resolve beyond an unclassified answer by introducing unsupported stronger meaning than answerMeaning.userSupportedMeaning establishes.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1568,7 +1568,7 @@ describe("applyValidatedProposal", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("57A regression: a legitimate decision-advancing answer classified as other may resolve its intended unknown", () => {
|
it("57F legitimate-answer regression: a grounded unclassified answer may resolve its intended unknown", () => {
|
||||||
const graph = makeCommercialUpdateFixture();
|
const graph = makeCommercialUpdateFixture();
|
||||||
const parentId = graph.activeUnknownNodeId;
|
const parentId = graph.activeUnknownNodeId;
|
||||||
|
|
||||||
@@ -1640,6 +1640,49 @@ describe("applyValidatedProposal", () => {
|
|||||||
expect(result.stage).toBeUndefined();
|
expect(result.stage).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("57F deterministic reproduction: pre-fix grounded unclassified answer would have been rejected by proposal-text constraint language", () => {
|
||||||
|
const graph = makeCommercialUpdateFixture();
|
||||||
|
const parentId = graph.activeUnknownNodeId;
|
||||||
|
|
||||||
|
const result = applyValidatedProposal({
|
||||||
|
situationGraph: graph,
|
||||||
|
answer:
|
||||||
|
"We're looking at this mainly for cost reduction — roughly £2M annual savings on office overhead.",
|
||||||
|
previousQuestion:
|
||||||
|
"What problem would this need to solve to justify continuing development?",
|
||||||
|
proposal: {
|
||||||
|
addedNodes: [],
|
||||||
|
updatedNodes: [
|
||||||
|
{
|
||||||
|
nodeId: parentId,
|
||||||
|
previousStatus: "unknown",
|
||||||
|
newStatus: "resolved",
|
||||||
|
previousValue: null,
|
||||||
|
newValue:
|
||||||
|
"Cost reduction, including approximately £2M annual office-overhead savings, is a stated reason for considering the relocation.",
|
||||||
|
reason:
|
||||||
|
"The answer establishes that cost reduction is the relevant preference/trade-off consideration for this decision.",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
addedEdges: [],
|
||||||
|
removedEdgeIds: [],
|
||||||
|
resolvedUnknownNodeIds: [parentId],
|
||||||
|
affectedNodeIds: [],
|
||||||
|
selectedQuestion: null,
|
||||||
|
answerMeaning: {
|
||||||
|
userSupportedMeaning:
|
||||||
|
"Cost reduction, including approximately £2M annual office-overhead savings, is a stated reason for considering the relocation.",
|
||||||
|
possibleInference: null,
|
||||||
|
supportCategory: "other",
|
||||||
|
resolutionGuidance: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.success).toBe(true);
|
||||||
|
expect(result.updatedSituationGraph.resolvedNodeIds).toContain(parentId);
|
||||||
|
});
|
||||||
|
|
||||||
it("unsafe unclassified answer: other is not automatically trusted when the proposal adds stronger unsupported meaning", () => {
|
it("unsafe unclassified answer: other is not automatically trusted when the proposal adds stronger unsupported meaning", () => {
|
||||||
const graph = makeCommercialUpdateFixture();
|
const graph = makeCommercialUpdateFixture();
|
||||||
const parentId = graph.activeUnknownNodeId;
|
const parentId = graph.activeUnknownNodeId;
|
||||||
@@ -1902,7 +1945,7 @@ describe("applyValidatedProposal", () => {
|
|||||||
expect(result.success).toBe(false);
|
expect(result.success).toBe(false);
|
||||||
expect(result.stage).toBe("proposal_compatibility");
|
expect(result.stage).toBe("proposal_compatibility");
|
||||||
expect(result.errors.join(" ")).toContain(
|
expect(result.errors.join(" ")).toContain(
|
||||||
"unsupported constraint or preference/trade-off distinction",
|
"unsupported stronger meaning than answerMeaning.userSupportedMeaning establishes",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user