Files
confidence-engine/docs/experiment-60b43.md
T

3.5 KiB

Experiment 60B.43 — Terminal post-mutation eligibility

Date: 2026-08-14 Branch: feature/post-mutation-terminal-eligibility-v0.38

Purpose

Extend the 60B.42 selector guard to the remaining post-mutation question-target eligibility checks so terminal-status unknown nodes cannot remain active or become the final selected question after mutation.

Starting point from 60B.42

60B.42 fixed selectActiveUnknownCandidate(...) so it no longer scores or returns unknown-kind nodes whose status is terminal:

  • known
  • resolved
  • contradicted

That closed one fallback source, but several independent post-mutation checks in apply-proposal.js still used weaker eligibility rules and could keep terminal nodes alive through other paths.

Remaining post-mutation eligibility changes

This experiment changed post-mutation eligibility only in lib/graph/apply-proposal.js.

Updated paths:

  • isSelectableUnresolvedUnknown(...)
  • remainingUnknownExists
  • carriedActiveUnknownStillUnresolved
  • listUnresolvedUnknownCandidates(...)
  • listEligibleUnknownCandidates(...)
  • selectPatternCompatibleUnknownCandidate(...)

Terminal-status rule applied post-mutation

A selectable unresolved post-mutation target now requires:

kind === unknown
status NOT IN [known, resolved, contradicted]
not in resolvedNodeIds

Important boundary preserved

validateSelectedQuestion(...) was not changed.

The closure proposal remains valid pre-mutation even when:

  • selectedQuestion.nodeId = n_product_launch_decision
  • the same proposal updates n_product_launch_decision -> known

Only after mutation is that now-terminal target discarded.

60B.37 deterministic regression

Added focused regression:

  • 60B.43 — terminal post-mutation target is cleared after valid decision closure

Reproduced the 60B.37-shaped closure:

  • existing active unknown: n_enterprise_customer_signing
  • proposal resolves n_enterprise_customer_signing
  • proposal updates n_product_launch_decision -> known
  • proposal still selects n_product_launch_decision
  • no added nodes or edges

Result

  • proposal applied successfully
  • customer factor resolved in place
  • decision became known in place
  • both options preserved unchanged
  • activeUnknownNodeId = null
  • final selectedQuestion = null

Fallback-to-real-unknown result

Added a second focused case where:

  • proposal-selected target becomes known
  • another genuine unresolved unknown remains after mutation

Result:

  • terminal known target discarded
  • remaining genuine unresolved candidate selected

Known-only post-mutation result

Added a valid mutated case where the final remaining unknown becomes known in the same mutation.

Result:

  • activeUnknownNodeId = null
  • selectedQuestion = null

Preservation checks

Focused run also preserved:

  • 60B.11 preferred-target behaviour
  • pricing prerequisite-first behaviour
  • resolved exclusion
  • contradicted exclusion

Validation

Command run:

npx vitest run tests/graph/apply-proposal.test.js -t "60B.43|60B.11|replaces downstream pricing"

Result:

  • PASS — 14 passed | 76 skipped

What remains unproven until live rerun

This deterministic bounded fix now clears the exact 60B.37-shaped stale target through the post-mutation production path under test.

What remains unproven until a live rerun is whether the full runtime/orchestration path with the real customer-signing closure answer produces the same null-question closure end state under live conditions.