refine answer meaning derivation for negation and qualification

This commit is contained in:
2026-08-09 09:48:08 +01:00
parent 7965375aff
commit 3e78d57aca
2 changed files with 196 additions and 12 deletions
+56 -12
View File
@@ -2745,6 +2745,46 @@ function proposalResolutionSummary(proposal) {
return { resolved, proposalText };
}
function mentionsHardConstraint(text) {
return (
text.includes("hard constraint") ||
text.includes("non-negotiable") ||
text.includes("dont want any increase in risk") ||
text.includes("do not want any increase in risk")
);
}
function mentionsNegatedHardConstraint(text) {
return (
text.includes("rather than a hard constraint") ||
text.includes("not a hard constraint") ||
text.includes("not an absolute constraint") ||
text.includes("preference rather than a hard constraint")
);
}
function hasDefaultPreferenceSignal(text) {
return (
text.includes("preference") ||
text.includes("normally") ||
text.includes("default preference") ||
text.includes("would usually") ||
text.includes("tend to")
);
}
function hasExceptionOrOverrideSignal(text) {
return (
text.includes(" but ") ||
text.includes(" if ") ||
text.includes("override") ||
text.includes("overridden") ||
text.includes("willing to accept") ||
text.includes("willingness to accept") ||
text.includes("accept some risk")
);
}
function deriveAnswerMeaningProfile(userSupportedMeaning) {
const meaningText = normaliseSemanticText(userSupportedMeaning);
@@ -2761,25 +2801,29 @@ function deriveAnswerMeaningProfile(userSupportedMeaning) {
};
}
if (
meaningText.includes("hard constraint") ||
meaningText.includes("non-negotiable") ||
meaningText.includes("dont want any increase in risk") ||
meaningText.includes("do not want any increase in risk")
) {
return {
category: "explicit_hard_constraint",
resolutionGuidance: "must_resolve",
};
}
const negatedHardConstraint = mentionsNegatedHardConstraint(meaningText);
const affirmativeHardConstraint =
mentionsHardConstraint(meaningText) && !negatedHardConstraint;
const conditionalPreferenceStructure =
(hasDefaultPreferenceSignal(meaningText) &&
hasExceptionOrOverrideSignal(meaningText)) ||
(negatedHardConstraint && hasExceptionOrOverrideSignal(meaningText)) ||
hasConditionalQualification(meaningText);
if (hasConditionalQualification(meaningText)) {
if (conditionalPreferenceStructure) {
return {
category: "conditional_tradeoff",
resolutionGuidance: "may_resolve",
};
}
if (affirmativeHardConstraint) {
return {
category: "explicit_hard_constraint",
resolutionGuidance: "must_resolve",
};
}
if (
meaningText.includes("matters more") ||
meaningText.includes("more important") ||
+140
View File
@@ -1212,6 +1212,100 @@ describe("applyValidatedProposal", () => {
expect(result.errors.join(" ")).toContain("conditional qualification");
});
it("B live-variant 1: negated hard-constraint mention stays conditional rather than explicit hard constraint", () => {
const { graph, riskUnknownId } = makeRiskClarificationFixture();
const result = applyValidatedProposal({
situationGraph: graph,
answer:
"I'd normally avoid more risk, but for the right opportunity I might accept some.",
previousQuestion:
"Is avoiding additional risk a hard constraint or a preference/trade-off?",
proposal: {
addedNodes: [],
updatedNodes: [
{
nodeId: riskUnknownId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue:
"Avoiding additional risk is a preference or trade-off rather than a hard constraint.",
reason:
"The answer shows a preference or trade-off rather than a hard constraint.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [riskUnknownId],
affectedNodeIds: [],
selectedQuestion: null,
answerMeaning: {
userSupportedMeaning:
"Avoiding additional risk is a strong preference rather than a hard constraint, with willingness to accept some risk if the opportunity is sufficiently compelling.",
possibleInference:
"The exact threshold for a sufficiently compelling opportunity remains undefined.",
supportCategory: "conditional_preference",
resolutionGuidance:
"Identify and quantify the threshold conditions that trigger risk acceptance.",
},
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain("conditional qualification");
expect(result.errors.join(" ")).not.toContain(
"explicitly stated hard constraint",
);
});
it("B live-variant 2: default preference plus override stays conditional rather than other", () => {
const { graph, riskUnknownId } = makeRiskClarificationFixture();
const result = applyValidatedProposal({
situationGraph: graph,
answer:
"I'd normally avoid more risk, but for the right opportunity I might accept some.",
previousQuestion:
"Is avoiding additional risk a hard constraint or a preference/trade-off?",
proposal: {
addedNodes: [],
updatedNodes: [
{
nodeId: riskUnknownId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue:
"Avoiding additional risk is a preference or trade-off rather than a hard constraint.",
reason:
"The answer shows a preference or trade-off rather than a hard constraint.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [riskUnknownId],
affectedNodeIds: [],
selectedQuestion: null,
answerMeaning: {
userSupportedMeaning:
"Avoiding additional risk is a default preference, but it can be overridden for sufficiently compelling opportunities.",
possibleInference: "The exact override threshold remains undefined.",
supportCategory: "conditional_preference",
resolutionGuidance: "needs more nuance",
},
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).toContain("conditional qualification");
expect(result.errors.join(" ")).not.toContain(
"does not clearly establish one of the protected reasoning categories",
);
});
it("Regression C: rejects unresolved uncertainty being treated as resolved", () => {
const { graph, riskUnknownId } = makeRiskClarificationFixture();
@@ -1341,6 +1435,52 @@ describe("applyValidatedProposal", () => {
);
});
it("negation safety: mentioning hard constraint in a negated comparison does not become affirmative hard constraint", () => {
const { graph, riskUnknownId } = makeRiskClarificationFixture();
const result = applyValidatedProposal({
situationGraph: graph,
answer:
"I'd normally avoid more risk, but for the right opportunity I might accept some.",
previousQuestion:
"Is avoiding additional risk a hard constraint or a preference/trade-off?",
proposal: {
addedNodes: [],
updatedNodes: [
{
nodeId: riskUnknownId,
previousStatus: "unknown",
newStatus: "resolved",
previousValue: null,
newValue:
"Avoiding additional risk is a preference or trade-off rather than a hard constraint.",
reason:
"The answer shows a preference or trade-off rather than a hard constraint.",
},
],
addedEdges: [],
removedEdgeIds: [],
resolvedUnknownNodeIds: [riskUnknownId],
affectedNodeIds: [],
selectedQuestion: null,
answerMeaning: {
userSupportedMeaning:
"Avoiding additional risk is a strong preference rather than a hard constraint.",
possibleInference:
"This indicates flexibility rather than an absolute prohibition.",
supportCategory: "conditional_preference",
resolutionGuidance: "needs more nuance",
},
},
});
expect(result.success).toBe(false);
expect(result.stage).toBe("proposal_compatibility");
expect(result.errors.join(" ")).not.toContain(
"weakens an explicitly stated hard constraint",
);
});
it("fails safely when answerMeaning does not clearly establish one of the protected categories", () => {
const { graph, riskUnknownId } = makeRiskClarificationFixture();