feat(confidence-engine): anchor focused frontier to investigation relevance

This commit is contained in:
2026-08-26 12:16:41 +01:00
parent cfd463d8b3
commit fdb173d0e9
2 changed files with 247 additions and 1 deletions
+3 -1
View File
@@ -97,8 +97,10 @@ Required top-level fields:
Field rules (semantic contract):
- targetNodeId must be included as a string identifying this investigation node
- observations: only meaning directly supported by what the user's answer states. Do not strengthen implications into observations.
- uncertainties: must be a JSON array containing exactly one string — the single nearest unresolved relationship exposed by this answer. This is the specific gap between what the answer established and what remains unknown right here. Do NOT widen the frontier: identify only the one thing that must be understood before you can know what to ask after it. Do NOT include everything else that might matter, future constraints, broader capability questions, other branches of the investigation, or possible remedies. The uncertainty must be narrow enough that one user answer could materially clarify it. Use ordinary language that a capable person with no specialist vocabulary can understand immediately. If the uncertainty needs abstract phrases, management jargon, specialist terminology, or several concepts joined together to express it, break the reasoning down again before returning it. Simple wording of an over-composed idea is still a failure: first ask "what is the smallest thing we actually do not know yet?" then express that one thing simply.
- uncertainties: must be a JSON array containing exactly one string — the single nearest unresolved proposition exposed by this answer, where "nearest" means the smallest investigation-relevant gap between what the answer established and what must be understood before this investigation can progress toward its target. Nearest is anchored to the central statement and target description for this investigation, not merely the smallest textual detail adjacent to the latest answer. Prefer the unresolved proposition that advances the current investigation over a local detail inside an already-working example. If the answer contains both (a) an already-working example with an unresolved internal detail and (b) another directly supported gap that must be understood before the investigation can progress, prefer the gap that advances the current investigation. Do NOT promote a detail inside an already-working example merely because it is smaller or mentioned nearby. Do NOT widen the frontier: identify only the one thing that must be understood before you can know what to ask after it. Do NOT include everything else that might matter, future constraints, broader capability questions, other branches of the investigation, or possible remedies. The uncertainty must be narrow enough that one user answer could materially clarify it. Use ordinary language that a capable person with no specialist vocabulary can understand immediately. If the uncertainty needs abstract phrases, management jargon, specialist terminology, or several concepts joined together to express it, break the reasoning down again before returning it. Simple wording of an over-composed idea is still a failure: first ask "what is the smallest thing we actually do not know yet?" then express that one thing simply.
- assumptions: what unstated proposition does the user's answer itself rely upon for it to make sense? Include only when such a proposition is genuinely attributable to the user's reasoning. The boundary is narrow: attribute only propositions that the user's answer would cease to make sense if they were false. Do NOT import plausible interpretations from the wider investigation context, scenario framing, domain relevance, strategic implications, or model-generated analysis into this field — those belong in uncertainties, relationships (where permitted), or possibleFollowUpQuestions. Do NOT connect a factual statement the user makes to a broader capability or constraint concept unless the user explicitly links them. Example: answering "I only have bank account access" to a question about delegation constraints does NOT assume that "delegation feasibility is contingent upon banking access" — it only states a fact about access, and connecting that fact to delegation feasibility is your own scenario-level inference, not a user-held assumption. If the user's answer does not contain or rely upon an identifiable assumption, return assumptions: []. Do NOT require verbatim copying from the user's answer; paraphrasing is allowed only when the reasoning genuinely relies on it.
Answer-dependence test: Only attribute an assumption if the user's answer needs that proposition to make sense. If the proposition could be false and the user's answer would still make complete sense, do not attribute it. One observed success in a single concrete example does NOT by itself establish a general rule about competence, readiness, training, safety, transferability, or similar tasks across other work. Do not generalise from one successful example into a broader capability/readiness rule unless the user explicitly or implicitly relies on that broader proposition.
- relationships: must connect two distinct propositions that the user's answer itself links. Do not create a relationship by merely restating, reformatting, or relabelling an observation. Co-mentioned facts do not themselves create a relationship. Tentative, speculative, or conditional language must not be promoted into an established relationship. If the answer does not directly establish a relationship, return relationships: [].
- possibleFollowUpQuestions: must be a JSON array containing exactly one string — your single best follow-up question. Example shape: ["one question"]. This question must directly investigate the single uncertainty returned in uncertainties (uncertainties[0] → possibleFollowUpQuestions[0]): one unresolved proposition mapped to one question designed to clarify it. The question must not introduce a second unresolved issue, must not broaden beyond the uncertainty it is meant to resolve, and must not contain more than one investigative step. Do not provide alternatives, a roadmap, or questions that belong after this one has been answered. A later question must be generated only after the current question has been answered and deconstructed. Do not ask about consequences, expansion, requirements, interventions, or other branches until the immediate unresolved relationship has been clarified. Those may become later questions after new evidence is obtained. Ask only what the Engine has earned the right to ask now. Each epistemic step waits its turn — do not combine steps that should happen in sequence across multiple turns: one question that investigates one thing only, never a bundle of future reasoning joined together. Before formulating, check whether the question tests a proposition against the current epistemic state: if an explanation, deficit, dependency, cause, intervention, recommendation, or solution has not been established by prior evidence, phrase the question so it tests whether that proposition is true rather than assuming it — verify the unresolved fact before seeking remedy. Prefer questions that identify what remains unknown, distinguish competing explanations, test whether a suspected factor actually matters, clarify scope, or identify what evidence would change the investigation. Do not jump to implementation details unless the answer has already established that intervention as the relevant next issue. Use ordinary language that a capable person with no specialist vocabulary can understand immediately. If the question needs abstract phrases, management jargon, specialist terminology, or several concepts joined together to express it, break the reasoning down again before returning it. Simple wording of an over-composed idea is still a failure: first ask "what is the smallest thing we actually do not know yet?" then express that one thing simply.
- cross-field ownership: preserve who or what owns each proposition. When a statement expresses the user's comfort, willingness, threshold, belief, uncertainty, preference, or judgement, keep it attached to that stance — do not elevate it into an objective requirement, capability fact, or situational constraint.
@@ -268,3 +268,247 @@ describe("FOCUSED_DECONSTRUCT_REGRESSION_CASES fixture integrity", () => {
expect(errors).toEqual([]);
});
});
// ── Frontier relevance: prompt contains investigation-relevance anchor ──
describe("buildFocusedDeconstructPrompt — frontier is anchored to investigation relevance", () => {
it("anchors 'nearest' to the central statement and target, not textual adjacency", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain('"nearest" means the smallest investigation-relevant gap');
expect(prompt).toContain("anchored to the central statement and target description");
});
it("explicitly prevents promoting working-example internal detail over investigation-progressing gaps", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("Do NOT promote a detail inside an already-working example");
});
it("requires preferring the gap that advances the current investigation", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("prefer the gap that advances the current investigation");
});
it("introduces working-example / structural-gap disambiguation condition", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("If the answer contains both");
});
it("preserves investigation-relevance qualifier (not just 'smallest unresolved')", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("investigation-relevant gap");
});
});
// ── Assumption attribution: prompt contains answer-dependence test ──
describe("buildFocusedDeconstructPrompt — assumption attribution tightened", () => {
it("requires an answer-dependence test before attributing assumptions", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("Answer-dependence test");
});
it("states the falsity test for attribution", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("could be false and the user's answer would still make complete sense");
});
it("prohibits generalising competence from one observed success", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("One observed success in a single concrete example does NOT by itself establish a general rule");
});
it("explicitly lists prohibited generalisation domains", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("competence, readiness, training, safety, transferability");
});
it("still permits assumptions: [] when no genuine assumption exists", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("assumptions: []");
});
it("does not suppress the original attribution principle", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("what unstated proposition does the user's answer itself rely upon");
});
it("does not suppress the original false-contradiction test", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("would cease to make sense if they were false");
});
});
// ── Preservation: existing prompt rules still present ──
describe("buildFocusedDeconstructPrompt — existing rules preserved", () => {
it("still requires exactly one uncertainty", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("exactly one string");
});
it("still requires exactly one follow-up question", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("exactly one string — your single best follow-up question");
});
it("still requires plain language (ordinary language for capable persons)", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("ordinary language that a capable person with no specialist vocabulary can understand immediately");
});
it("still prohibits future remedies and branches", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("future constraints");
});
it("still prohibits observation restatement as relationship", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("Do not create a relationship by merely restating");
});
it("still prohibits promotion of tentative meaning to relationship", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("Tentative, speculative, or conditional language must not be promoted");
});
it("still preserves cross-field ownership rule", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("cross-field ownership");
});
it("still prohibits importing scenario-level inference into assumptions", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("Do NOT import plausible interpretations from the wider investigation context");
});
it("still prohibits graph-mutation semantics", () => {
const prompt = buildFocusedDeconstructPrompt({
targetLabel: "X",
targetDescription: "Y",
centralStatement: "Z",
question: "Q?",
answer: "A.",
});
expect(prompt).toContain("Do NOT output graph mutations");
});
});