reasoning: add proposal-level answer meaning guard

- Add answerMeaning schema with supportCategory and resolutionGuidance enums
- Add pre-mutation guard that validates proposal alignment with answerMeaning
- Update prompt builder to instruct the model on answerMeaning contract
- Add tests for schema, guard logic, parsing defaults, and regression cases A-D
This commit is contained in:
2026-08-09 07:07:21 +01:00
parent 8c1036ecd0
commit 0d7ad5775c
7 changed files with 470 additions and 0 deletions
+27
View File
@@ -181,6 +181,13 @@ describe("graphUpdateSchema", () => {
question: "What does this new node mean?",
reason: "A follow-up unknown remains.",
},
answerMeaning: {
userSupportedMeaning:
"The user directly established a concrete answer.",
possibleInference: null,
supportCategory: "other",
resolutionGuidance: "may_resolve",
},
});
expect(result.success).toBe(true);
});
@@ -192,6 +199,26 @@ describe("graphUpdateSchema", () => {
expect(result.success).toBe(true);
});
it("allows null answerMeaning", () => {
const result = graphUpdateSchema.safeParse({
answerMeaning: null,
});
expect(result.success).toBe(true);
});
it("validates structured answerMeaning when present", () => {
const result = graphUpdateSchema.safeParse({
answerMeaning: {
userSupportedMeaning: "Risk matters more to me.",
possibleInference:
"This may imply caution, but does not establish a hard constraint.",
supportCategory: "relative_priority_only",
resolutionGuidance: "must_remain_unresolved",
},
});
expect(result.success).toBe(true);
});
it("rejects update with invalid node kind in addedNodes", () => {
const invalid = graphUpdateSchema.safeParse({
addedNodes: [