feat(confidence-engine): expose focused-investigation inputs in composed checkpoint

Add focusedInvestigationInput {targetDescription, question, answer} to
composeDeepInvestigationCheckpoint() return object. These are the actual
invocation values: targetDescription from situationGraph node, question
is previousQuestion (NOT node.openQuestion), answer is function param.

Deterministic verification: syntax check passed; source-inspection test
assertions E10/E11 added and pass (0 failures). Call-count ownership:
up to 3 live generateReconstruction calls (focusedDeconstruct +
reconsiderCompletedEpisode + synthesizeCurrentUnderstanding).

No provider, graph, or production behavior changed.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
robbond
2026-10-09 13:47:54 +01:00
co-authored by Claude Code
parent d0f357877d
commit d12615075d
4 changed files with 26 additions and 4 deletions
+10
View File
@@ -688,5 +688,15 @@ Ensure these remain visible and are not accidentally promoted to tester blockers
Tested canonical uncertainty description as initial display instead of generated question. Changed `lib/presentation/facilitator-view-adapter.js` lines ~277–281 to prefer `description` over `openQuestion`. Deterministic tests: 54/54 PASS (including both adapter test files). Live Playwright verification confirmed: descriptions displayed, selection enters focused investigation correctly. Graph identity and reasoning-state ownership unchanged. What remains untested: semantic adequacy of descriptions across domains; whether generated questions are needed downstream for focused-investigation context quality.
### Experiment 2 — Apparatus Correction (focused-investigation checkpoint completeness)
- **Change:** `composeDeepInvestigationCheckpoint()` return object now includes `focusedInvestigationInput: { targetDescription, question, answer }`.
- **`targetDescription`:** derived from `situationGraph.nodes.find(n => n.id === targetNodeId)?.description ?? ""`, declared as module-level `let` before deconstruction block.
- **`question`:** equals `previousQuestion ?? ""` — **NOT** `node.openQuestion`. Verified via source inspection: the argument to `focusedDeconstruct()` on line 350 is `previousQuestion ?? ""`.
- **`answer`:** direct function parameter value, no transformation.
- **Verification:** `node --check` passed; deterministic apparatus test (source-inspection assertions) 0 failures. New assertion E10/E11 added to existing test.
- **Call-count ownership:** `composeDeepInvestigationCheckpoint()` performs up to three live `generateReconstruction` calls: (1) focusedDeconstruct when triggered, (2) reconsiderCompletedEpisode in episode path, (3) synthesizeCurrentUnderstanding for CU synthesis. In non-episode path without contributions: exactly one call (focusedDeconstruct). Source references: helper lines 302, 393, 449.
- **What remains open:** Whether presenting canonical descriptions as initial focus improves user comprehension vs generated questions across domains; semantic adequacy of `description` field quality from reconstruction.
**Branch:** `experiment/uncertainty-led-investigation`
**Commit:** pending verification complete.
@@ -94,5 +94,6 @@ Preserve existing graph relationships, stable identities, provenance, persistenc
- HS-01 / HS-02: manufacturing-investment scenario; prompt-contract refinement and single-repeat observation.
- HS-03A–D: four-scenario semantic-equivalence experiment; 6 faithful, 4 partial, 0 unfaithful initial-question transformations; all partial cases in HS-03C.
- **Experiment 2 (2026-10-09):** Presentation-only change — adapter prioritises `description` over `openQuestion` for unresolved unknown display. Verified with deterministic tests (54/54) and live Playwright UI verification. Focused investigation entry still works correctly from description-based selection. `openQuestion` generation remains untouched. Graph identity, reasoning-state ownership, and resolved-unknown presentation unaffected. Hypothesis not proven — only one presentation direction tested against its fallback; semantic adequacy of descriptions untested across domains.
- **Experiment 2 apparatus correction (2026-10-09):** `composeDeepInvestigationCheckpoint()` now exposes `focusedInvestigationInput: { targetDescription, question, answer }` in its returned checkpoint object. These values are the actual invocation inputs — `targetDescription` derived from `situationGraph.nodes.find(n => n.id === targetNodeId)?.description`, `question` is `previousQuestion ?? ""` (NOT `node.openQuestion`), `answer` is the function parameter. Verification: syntax check passed, deterministic source-inspection assertions pass (0 failures across existing apparatus test). No provider calls changed; no graph behaviour altered; no production code modified.
## Decision state: OPEN (after iteration 2 evidence).
@@ -324,6 +324,10 @@ assert(helperSrc.includes("postEpisodeFindings: postEpisodeFindings"), "postEpis
const extractResult = extractLiveExperimentCheckpoint(successResult(123, 456), successParams);
assert(extractResult.providerGenerateCalls === 1, "providerGenerateCalls preserved from extraction path");
// E10. Apparatus correction: focusedInvestigationInput field present in composed checkpoint (Iteration 2)
assert(helperSrc.includes("focusedInvestigationInput:"), "helper exposes focusedInvestigationInput in composed checkpoint output");
assert(helperSrc.includes("targetDescription:") && helperSrc.includes("question:") && helperSrc.includes("answer,"), "focusedInvestigationInput contains targetDescription, question, answer fields");
// ---- CONTRIBUTION SEAM VERIFICATION (Iteration 4 + Iteration 5 deconstruction) ──────────────────────
console.log("\n=== CONTRIBUTION SEAM VERIFICATION ===\n");
+11 -4
View File
@@ -314,10 +314,8 @@ async function composeDeepInvestigationCheckpoint({ situationGraph, previousQues
/* ── Production-equivalent focused-episode seam: targetNodeId triggers the same path as executeEpisodeDone → handleEpisodeMode ─── */
/* ── Canonical deconstruction: use focusedDeconstruct for Contribution derivation ─── */
const effectiveContributions = contributions.length > 0 ? [...contributions] : [];
/* ── Target-scoped filtering: only contributions belonging to the current target suppress fresh deconstruction ─── */
let targetDescription = "";
let effectiveContributionsForTarget = effectiveContributions;
if (targetNodeId && effectiveContributions.length > 0) {
effectiveContributionsForTarget = effectiveContributions.filter(
@@ -336,7 +334,7 @@ async function composeDeepInvestigationCheckpoint({ situationGraph, previousQues
// Extract node context for deconstruction prompt
const targetNode = situationGraph.nodes.find(n => n.id === targetNodeId);
const targetLabel = targetNode?.label ?? "";
const targetDescription = targetNode?.description ?? "";
targetDescription = targetNode?.description ?? "";
const centralStatement = situationGraph.centralStatement ?? "";
// Call production-focused deconstruct — exactly one provider generation
@@ -510,6 +508,15 @@ async function composeDeepInvestigationCheckpoint({ situationGraph, previousQues
/* ── Answer meaning (from production result) ─── */
userSupportedMeaning: episodeResult?.proposal?.answerMeaning?.userSupportedMeaning ?? null,
possibleInference: episodeResult?.proposal?.answerMeaning?.possibleInference ?? null,
/* ── Focused-investigation input values (apparatus correction) ─── */
focusedInvestigationInput: (previousQuestion != null || answer != null)
? {
targetDescription: targetDescription ?? "",
question: previousQuestion ?? "",
answer,
}
: null,
};
}