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
+10
View File
@@ -69,6 +69,7 @@ The JSON object must contain exactly these top-level fields:
- resolvedUnknownNodeIds
- affectedNodeIds
- selectedQuestion
- answerMeaning
## Required Shapes
- addedNodes: array of nodes using these exact keys:
@@ -82,6 +83,8 @@ The JSON object must contain exactly these top-level fields:
- affectedNodeIds: array of strings
- selectedQuestion: either null or an object using these exact keys:
nodeId, question, reason
- answerMeaning: either null or an object using these exact keys:
userSupportedMeaning, possibleInference, supportCategory, resolutionGuidance
## Proposal Rules
1. Propose changes only. Never return a replacement graph.
@@ -111,6 +114,12 @@ The JSON object must contain exactly these top-level fields:
23. Never use unknown enum values.
24. Do not change existing IDs.
25. Do not replace the whole graph, and do not restate unchanged graph content inside the proposal.
26. answerMeaning.userSupportedMeaning must state only what the user's answer directly supports.
27. Put any stronger interpretation in answerMeaning.possibleInference, not in userSupportedMeaning.
28. If the answer is only a relative priority statement, use supportCategory=relative_priority_only and resolutionGuidance=must_remain_unresolved.
29. If the answer is conditional or qualified, preserve that qualification explicitly in userSupportedMeaning.
30. If the answer says the user is unsure or does not resolve the distinction, use supportCategory=uncertain and resolutionGuidance=must_remain_unresolved.
31. If the answer explicitly states a hard constraint, use supportCategory=explicit_hard_constraint and resolutionGuidance=must_resolve.
## Additional Guidance
- If the answer only clarifies an existing unknown, prefer updatedNodes and resolvedUnknownNodeIds over creating duplicate nodes.
@@ -120,6 +129,7 @@ The JSON object must contain exactly these top-level fields:
- If you add a new unknown, its description must do two jobs in one sentence: what is unknown, and why resolving it matters for the case.
- Treat selectedQuestion as a candidate only; the engine will apply deterministic information-value scoring after validation.
- If the answer does not justify a change, return empty arrays for every category.
- Use answerMeaning to preserve the answer's direct meaning even when the graph change remains unresolved.
## Example Constraint Reminder
${formatExampleAnswerBlock()}