prompt: remove semantic-only mutation conflict
This commit is contained in:
@@ -128,8 +128,9 @@ The JSON object must contain exactly these top-level fields:
|
||||
- If you add a new unknown, do not leave it floating: connect it with an added edge to the relevant decision/context node created or updated from the answer.
|
||||
- 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.
|
||||
- If rule #6 does not apply (the answer contains no user-supported meaning that requires graph progress) and there is no other justification for change, return empty arrays for every category.
|
||||
- If rule #6 applies but you choose an update/refinement of existing structure, resolve an existing unknown, or add justified new structure, your structural proposal plus answerMeaning together represent the complete response — answerMeaning preserves semantic fidelity while structural mutation handles graph progress; neither replaces the other.
|
||||
- If you add a new unknown with addedNodes, connect it with at least one addedEdge to an existing updated/resolved node or to a newly added non-unknown node from the answer.
|
||||
|
||||
## Example Constraint Reminder
|
||||
${formatExampleAnswerBlock()}
|
||||
|
||||
@@ -177,4 +177,107 @@ describe("buildGraphUpdatePrompt — semantic-to-mutation MUST rule", () => {
|
||||
);
|
||||
expect(mustRuleMatch[0]).toContain("userSupportedMeaning");
|
||||
});
|
||||
|
||||
// ── 57J.43 — no surviving semantic-only/no-op conflict ──
|
||||
|
||||
it("PASS: no direct contradiction — MUST rule is not undermined by empty-array permission", () => {
|
||||
const prompt = buildGraphUpdatePrompt(makeContext());
|
||||
|
||||
// The MUST rule must exist...
|
||||
expect(prompt).toContain(
|
||||
"MUST express its effect through structural mutation",
|
||||
);
|
||||
|
||||
// ...and the empty-array permission must NOT be unconditional.
|
||||
// It must reference rule #6 as a condition, meaning it cannot apply
|
||||
// when the MUST rule fires.
|
||||
const additionalGuidance = prompt.split("## Additional Guidance")[1];
|
||||
|
||||
// The old conflicting wording must be absent:
|
||||
expect(additionalGuidance).not.toContain(
|
||||
"If the answer does not justify a change, return empty arrays",
|
||||
);
|
||||
|
||||
// The new permission must reference rule #6:
|
||||
expect(additionalGuidance).toContain("rule #6");
|
||||
});
|
||||
|
||||
it("PASS: legitimate true no-op preserved — empty mutation allowed when rule #6 does not apply", () => {
|
||||
const prompt = buildGraphUpdatePrompt(makeContext());
|
||||
const additionalGuidance = prompt.split("## Additional Guidance")[1];
|
||||
|
||||
// The corrected bullet must still allow empty arrays, but only
|
||||
// when rule #6 does not apply (no consequential meaning).
|
||||
expect(additionalGuidance).toContain(
|
||||
"return empty arrays for every category",
|
||||
);
|
||||
// And it must be conditioned:
|
||||
expect(additionalGuidance).toContain("does not apply");
|
||||
});
|
||||
|
||||
it("PASS: answerMeaning is not structural progress", () => {
|
||||
const prompt = buildGraphUpdatePrompt(makeContext());
|
||||
const additionalGuidance = prompt.split("## Additional Guidance")[1];
|
||||
|
||||
// Must explicitly separate answerMeaning from graph mutation:
|
||||
expect(additionalGuidance).toContain("preserves semantic fidelity");
|
||||
// And must not say answerMeaning alone can substitute for mutation:
|
||||
expect(additionalGuidance).not.toContain(
|
||||
"even when the graph change remains unresolved",
|
||||
);
|
||||
});
|
||||
|
||||
it("PASS: duplicate protection preserved — no weakening of existing-duplicate rules", () => {
|
||||
const prompt = buildGraphUpdatePrompt(makeContext());
|
||||
// Rule #4 and rule #11 must still exist with their substance:
|
||||
expect(prompt).toContain("genuinely new concepts");
|
||||
expect(prompt).toContain("duplicate unknowns");
|
||||
// Additional Guidance preference for update over add:
|
||||
const additionalGuidance = prompt.split("## Additional Guidance")[1];
|
||||
expect(additionalGuidance).toContain("prefer updatedNodes and resolvedUnknownNodeIds over creating duplicate nodes");
|
||||
});
|
||||
|
||||
it("PASS: update/refine route preserved — no new mandatory-add requirement", () => {
|
||||
const prompt = buildGraphUpdatePrompt(makeContext());
|
||||
|
||||
// The MUST rule permits update/refine (not just add):
|
||||
expect(prompt).toContain("update/refinement of existing structure");
|
||||
// Additional guidance still encourages preferring updates:
|
||||
const additionalGuidance = prompt.split("## Additional Guidance")[1];
|
||||
expect(additionalGuidance).toContain("prefer updatedNodes and resolvedUnknownNodeIds over creating duplicate nodes");
|
||||
expect(additionalGuidance).toContain("update that node rather than creating only a parallel observation");
|
||||
});
|
||||
|
||||
it("PASS: possibleInference separation preserved — not converted to mandatory mutation", () => {
|
||||
const fullPrompt = buildGraphUpdatePrompt(makeContext());
|
||||
|
||||
// Rule #27 must still separate possibleInference from userSupportedMeaning:
|
||||
expect(fullPrompt).toContain(
|
||||
"Put any stronger interpretation in answerMeaning.possibleInference, not in userSupportedMeaning",
|
||||
);
|
||||
|
||||
// The corrected Additional Guidance must reference the mutation trigger via rule #6
|
||||
// (which itself references userSupportedMeaning), not possibleInference:
|
||||
const additionalGuidance = fullPrompt.split("## Additional Guidance")[1];
|
||||
expect(additionalGuidance).toContain("rule #6");
|
||||
expect(additionalGuidance).not.toContain("possibleInference");
|
||||
|
||||
// Rule #27 exists in the prompt (separation preserved):
|
||||
expect(fullPrompt).toContain("answerMeaning.possibleInference, not in userSupportedMeaning");
|
||||
});
|
||||
|
||||
it("PASS: no action-selection machinery added — no keyword routing or node-kind decision table", () => {
|
||||
const fullPrompt = buildGraphUpdatePrompt(makeContext());
|
||||
|
||||
// Confirm we did not add new provider-specific routing:
|
||||
expect(fullPrompt).not.toContain("qwen");
|
||||
expect(fullPrompt).not.toContain("claude");
|
||||
expect(fullPrompt).not.toContain("gpt");
|
||||
|
||||
// No keyword-based node-kind decision table:
|
||||
expect(fullPrompt).not.toContain("keyword");
|
||||
|
||||
// No mandatory-add logic:
|
||||
expect(fullPrompt).not.toContain("must add a new node");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user