prompt: remove semantic-only mutation conflict

This commit is contained in:
2026-08-11 13:22:29 +01:00
parent 0c477adea9
commit 359ccc4ba9
2 changed files with 106 additions and 2 deletions
+103
View File
@@ -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");
});
});