Remove the 140-line Iteration 16 test section (commit 5d4e7b5) that
represented manually supplied checkpoint values as evidence of
target-scoped contribution behaviour. The section used extractLiveExperimentCheckpoint
to construct mock result objects simulating multi-episode state transitions
but could not observe contributions — the deterministic seam has no
contributions field in its return shape.
Preserves: all pre-existing checkpoint tests, Iteration 15 source-level
assertions, synthetic CU synthesis tests, and existing helper imports.
Add Iteration 16 test extension that documents the behavioral evidence
boundary for target-scoped contribution filtering:
- Observable via extractLiveExperimentCheckpoint:
* Node A pre-episode graph state (graphCheckpoint.nodeCount)
* B's fresh deconstruction trigger (providerGenerateCalls increments)
* Graph/findings continuity (reasoningState turnCount advanced)
- Blocked from deterministic seam (no contributions field in checkpoint):
* Historical contribution retention for non-current targets
* B contribution associated with targetNodeId
* Both A and B surviving in postEpisodeContributions
* B prep scope receiving B-specific contribution
Uses mock result objects to simulate the two-target sequence
(n_enterprise_customer_signing -> n_product_launch_decision) and
explicitly documents which assertions can and cannot be verified.
Historical contributions for a different Open Question node no longer
suppress fresh focused deconstruction of the current target. Only
contributions whose targetNodeId matches the current target are counted
towards suppressing redundant deconstruction.
Adds deriveInvestigationLearning to episode-preparation.js: pure function that maps resolvedNodeIds + Contributions + Findings to investigation learning propositions, preserving node.label question text and contribution-provenance ordering.
Owning tests prove: correct provenance, cross-question isolation, eligibility rule (null/agree eligible; not_quite/not_relevant excluded), unresolved exclusion, no-eligible-material omission, text preservation, and provenance authority over originatingTargetNodeId shortcut.
- Zod validator: plausibleInterpretations accepts empty string (zero interpretations) while remaining required and string-typed
- Prompt instruction: SECTION B now explicitly requests "" instead of absence prose when no plausible inputs exist
- Report generation/update paths derive hasPlausibleInterpretations from actual synthesized data rather than hard-coding true
- Tests: updated validation contract, added hasPlausibleInterpretations derivation assertions, updated seam tests to use derived values
Production: synthesizeInvestigationOverview() now passes providerResult.response
to validateOverviewResponse() instead of the raw envelope, matching the proven
pattern in current-understanding-synthesis.js.
Regression: fakeProvider returns real-provider envelope shape { response, providerApiPath }
and four new regression tests verify unwrapping succeeds with valid response
and fails correctly with invalid response inside the envelope.
Handoff: documented defect confirmed, fix applied, and owning regression added.