Add two new capabilities:
1. isUserConfirmationOfNoRemainingUncertainty(answer) — bounded,
deterministic raw-answer confirmation that no other material uncertainty
remains after a decision factor has been resolved. Matches an explicit
phrase family (e.g. 'no remaining material uncertainty', 'no other
material uncertainties remain') plus two bounded regex patterns, while
rejecting contradictory wording ('still another material uncertainty',
'I am not saying...').
2. Decision-sufficiency closure integration point in applyValidatedProposal,
positioned after post-mutation/post-propagation and before final
active-target selection. When all represented material factors are
resolved AND the raw user answer confirms sufficiency, resolves the
existing parent decision in place (status → 'resolved') and clears
the active unknown target.
Uses a virtual 'resolved this turn' set because node statuses have not
yet been reconciled at the integration point. Tests cover: exact fixture
wording from 60B.56, bounded paraphrases, absence-of-confirmation
(non-closure), remaining-factors (blockage), contradictory wording
(rejection), negated phrases (rejection), and vague completion language
(exclusion).
Read-only inspection of 8 files (prompt-builder.js, schema.js, utils.js,
apply-proposal.js, orchestrator.js, experiment-60b1.md, experiment-60b2.md,
current-handoff.md). No code changes.
Key findings:
- Prompt has no independent materiality/sufficiency rule (Rule 20 says null
selectedQuestion when 'no consequential unresolved unknown' but doesn't define
what makes an unknown non-consequential)
- Validator performs structural checks only, no evidence sufficiency evaluation
- No cross-option comparison logic in propagateResolvedChildEvidence
- Schema has no materiality or couldChangeDecision field
- 60B.1 resolved WITH 'no other material differences' cue; 60B.2 continued
WITHOUT it, despite internally computing ~3.6 month payback
Classification: C — NO SUFFICIENCY RULE + CONTINUATION BIAS
Missing distinction: MATERIALITY / DECISION-RELEVANCE RULE
Implementation of Candidate B (unknown+option) from decision architecture
design in 60A.2. Adds two new primitives to the situation graph:
Schema (lib/graph/schema.js):
- SituationKind.option — a choice available within a decision context
- SituationRelationship.contained_in — links option → its parent unknown context
Prompt rules (lib/graph/prompt-builder.js):
- Section added: Decision Option Structure Rules with 5 numbered instructions
governing when/how to create option nodes, link them via contained_in,
attach consequences to specific options, and handle do-nothing alternatives.
Explicitly forbids alternative_to edges and is_baseline/is_default flags.
Tests (446 new lines):
- schema.test.js: +300 — enum completeness updates, option kind validation,
contained_in edge validation, native two-option graph fixture (~25 new tests)
- prompt-builder.test.js: +133 — focused rules verification for all 5 rule points,
negative checks (no relocation/savings/example-specific wording, no alternative_to
requirement, baseline flag prohibition context)
No production code paths affected beyond the two enum additions; existing node and
edge kinds remain unchanged. No Ollama calls, no live API calls.
Diagnoses the root cause of the persistent pattern from 59B.2-59B.4
where explicit dual-option input collapsed into a single undifferentiated
unknown node. Concludes the graph vocabulary lacks first-class primitives
for options/decisions (not primarily a prompt issue). Identifies three
missing primitives: option node kind, decision node kind, alternative_of
edge type. Recommends ~25-line schema addition for 60A.2 implementation.
Add FIXTURE_MODE=updateOnly support that bypasses Start and sends the
committed fixture (tests/fixtures/pre-anchored-update-savings-realism.json)
directly as an Update request body through production HTTP route.
scripts/reproduce-multi-turn-investigation.mjs:
- Added ESM imports for deterministic fixture loading (fs, fileURLToPath, path)
- Added FIXTURE_PATH constant pointing to committed fixture
- Added fixtureMode env-var selector and runUpdateOnlyMode() function
- Validates ANSWER_2 before any live call (zero calls if missing)
- Verifies single savings-realism anchor invariant on load
- Preserves all hardened capture fields in pre-anchored mode
- Normal-mode Start→Update chain preserved under guard clause
tests/reproduce-multi-turn-investigation.harness.test.js:
- Added 7 new harness tests for pre-anchored scenarios (46 total, all pass)
- Updated runPreAnchoredSimulation to persist rejectedProposalSnapshot on rejection
- Added runPreAnchoredSimulationWithBlock() helper
docs/:
- New docs/experiment-57j78.md with full apparatus description
- Updated docs/current-handoff.md with 57J.78 section