Files
confidence-engine/docs/archive/experiments/decision-closure-integration/experiment-60b15.md
T

17 KiB
Raw Blame History

Experiment 60B.15 — Structural Reasoning-Context Embedding Predicate

Branch: feature/question-target-alignment-v0.27
Date: 2026-08-13
Status: COMPLETE (read-only design analysis)
Type: ARCHITECTURAL DESIGN — Define the smallest deterministic structural predicate for reasoning-pattern compatibility normalization

Objective

Choose the smallest deterministic structural predicate that classifies a new unknown as embedded in an active decision context without becoming so permissive that genuine pattern transitions are hidden.

This follows 60B.14's recommendation of a compatibility fallback (Candidate D) but addresses its unresolved boundary question: what exact structural relationship is strong enough to count as "embedded" without enabling arbitrary graph connectivity?

Context Route Summary

Source files examined

File Key functions / definitions Lines read
lib/graph/question-formulator.js buildParentChain (888899) 12
lib/graph/question-formulator.js hasDecisionContext (901921) 21
lib/graph/question-formulator.js collectRelatedNodes (2549) 25
lib/graph/question-formulator.js selectReasoningPattern (10301101) 72
lib/graph/apply-proposal.js determineActiveReasoningPattern (18041832) 29
lib/graph/apply-proposal.js inferIntrinsicNodePattern (18341881) 48
lib/graph/apply-proposal.js assessReasoningPatternCompatibility (18831908) 26
lib/graph/schema.js SituationRelationship enum (7789) 13
lib/graph/schema.js node-level arrays (6770) 4

Test coverage examined

  • Genuine transition case: tests/graph/apply-proposal.test.js:2486 — "does not allow a decision-mode active unknown to remain a comparison child"
  • Pattern selection: tests/graph/reasoning-pattern-selection.test.js — selects reasoning patterns based on context and text analysis
  • No dedicated tests for determineActiveReasoningPattern inheritance; coverage exists only through integration in apply-proposal tests.

FIXED CASE (60B.12)

Active decision context:
  n_relocation_decision  kind=unknown, label="Which option leaves us better off overall?"

Option:
  opt_relocate           kind=option, contained_in → n_relocation_decision

New unresolved factor:
  n_client_retention_uncertainty  kind=unknown, label="Will our largest client leave if we relocate?"

Edge:
  n_client_retention_uncerness → opt_relocate  relationship=may_cause

Intrinsic wording ("will X happen?") infers pattern diagnosis.
Active context is decision.
ALLOWED_NODE_PATTERNS_BY_ACTIVE_PATTERN["decision"] = ["decision", "definition"].
Current result: REJECT (diagnosis not in allowed list).


AVAILABLE STRUCTURAL SIGNALS

Node-level arrays

Signal Type Semantic classification
parentId string (nullable) CONTEXT MEMBERSHIP — direct parent-child hierarchy. Unambiguous ownership within a tree structure.
childIds string[] CONTEXT MEMBERSHIP (reverse) — indicates this node contains the listed nodes. Same semantic force as parentId but in reverse direction.

Node-level relationship arrays

Signal Type Semantic classification
dependsOn (node array) string[] PREREQUISITE — "I cannot be evaluated without X." Forward link to prerequisites.
affects (node array) string[] WEAK / AMBIGUOUS — indicates impact but not necessarily direct consequence. Directional but causally loose.

Edge relationships (SituationRelationship enum)

Signal Type Semantic classification
contained_in SituationEdge CONTEXT MEMBERSHIP — explicit structural containment. Strongest non-hierarchical signal for "belongs inside."
may_cause SituationEdge CONSEQUENCE — evaluates whether X could cause Y. In decision context, this is a material factor (uncertainty about consequence).
causes SituationEdge CONSEQUENCE (strong) — definitive causal link to consequence. Stronger than may_cause but same semantic family.
supports SituationEdge EVIDENCE — provides evidence for the target node's claim. Not decision-factor membership, not prerequisite.
measures SituationEdge EVIDENCE — quantifies or measures the target. Evidence collection, not core decision reasoning.
depends_on SituationEdge PREREQUISITE — "I need this before I can be evaluated." Same semantic family as node-level dependsOn but edge-directed.
weakens SituationEdge WEAKENING_EVIDENCE — undermines the target's claim. Opposite of supports; same category for embedding purposes.
contradicts SituationEdge CONTRADICTING — presents incompatible claims. Could signal genuine pattern transition rather than embedded factor.
compares_with SituationEdge COMPARISON — structured comparison between nodes. May indicate evidence gathering or cross-pattern boundary.
updates SituationEdge TEMPORAL — indicates temporal relationship. Ambiguous for embedding purposes.
other SituationEdge AMBIGUOUS — catch-all, no semantic signal for embedding.

Relationship traversal in collectRelatedNodes

// From node arrays: dependsOn[], affects[]
relatedIds.add(...node.dependsOn);
relatedIds.add(...node.affects);
relatedIds.add(...node.childIds);
if (node.parentId) relatedIds.add(node.parentId);
// From graph edges (both directions):
for (edge of graph.edges) {
  if (edge.fromNodeId === node.id) relatedIds.add(edge.toNodeId);
  if (edge.toNodeId === node.id) relatedIds.add(edge.fromNodeId);
}

All edge types are traversed bidirectionally without semantic discrimination. This is the current state that Candidate C would rely on.


GENUINE TRANSITION CHECK

Existing example/test used: tests/graph/apply-proposal.test.js:2486 — "does not allow a decision-mode active unknown to remain a comparison child"

Scenario:

n-commercial-parent  kind=unknown, status=unknown, label="..." (decision-mode)
  └─ n-commercial-comparison-child  parentId → n-commercial-parent
       label: "How the two observations were measured"
       description: "Need evidence about the measure used for each observation before comparing them."

Current active pattern: decision (from n-commercial-parent via determineActiveReasoningPattern)
Different legitimate node pattern: comparison (from intrinsic text analysis of "measure", "compared")

Is this a genuine transition? YES — the node's text genuinely indicates comparison reasoning. The ALLOWED_NODE_PATTERNS_BY_ACTIVE_PATTERN correctly lists it as NOT allowed under decision, and the test verifies rejection with incompatibleNodeIds containing the comparison child.

This is the boundary we must preserve. A candidate predicate that incorrectly normalizes this case to "decision" would be wrong — the comparison unknown legitimately signals a different reasoning mode.


CANDIDATE A — PARENT-CHAIN ONLY

Predicate:

New node structurally embedded if its parentId/ancestor chain reaches a node whose active pattern is the current active pattern.

For 60B.12, this traces: client_retention_uncertainty.parentId → opt_relocate → opt_relocate.parentId → n_relocation_decision.

Fixes 60B.12: YES (direct parentId chain exists in the fixture).
Semantic precision: HIGH — parentId is unambiguous ownership.
Coverage: MEDIUM — only catches hierarchically nested nodes. Misses edge-connected nodes without explicit parentId.
False-compatibility risk: LOW — parent-chain has no false positives by definition.

Genuine transition preserved: YES — the test at 2486 has a direct parentId chain to n-commercial-parent (decision), so the pattern comparison itself (not structural embedding) correctly rejects it. This candidate does not change that outcome.


CANDIDATE B — DECISION-OPTION PATH

Predicate:

New unknown structurally embedded in decision context if it links to an option node that is contained_in the active decision unknown.

For 60B.12, this traces through edge types from the new unknown to the option, then up to the decision.

Incoming relationship Classification Reasoning
may_cause SUFFICIENT The unknown explicitly evaluates whether it causes the option — a material decision factor. This is the exact 60B.12 case.
causes SUFFICIENT Definitive causal link to option consequence. Stronger than may_cause but same semantic family.
affects SUFFICIENT Indicates impact on the option. In decision context, affecting an option is evaluating a decision-relevant uncertainty.
depends_on AMBIGUOUS Could be prerequisite to option (genuine factor) or prerequisite to something else. Needs path analysis to disambiguate.
supports INSUFFICIENT Provides evidence for the option but is not itself a decision factor — it's supporting data, not decision reasoning.
measures INSUFFICIENT Evidence collection node. Not part of core decision reasoning; belongs to the evidence-gathering track.

Fixes 60B.12: YES (may_cause is SUFFICIENT).
Genuine transition preserved: DEBATABLE — if an unknown has both may_cause and contradicts edges, the semantic signal becomes mixed. A node that genuinely transitions to contradiction while also affecting an option would be normalized incorrectly.


CANDIDATE C — ANY GRAPH PATH

Predicate:

Any path of existing edges from new unknown to active-context node counts as embedding.

Fixes 60B.12: YES (path exists via may_cause).
Too permissive: YES — any node connected by a chain of supports/updates/other edges would be embedded regardless of semantic relevance. A node that merely references the decision context without participating in its reasoning is incorrectly included.
Genuine transition preserved: NO — overly broad connectivity masks genuine pattern transitions because virtually everything connects to the decision through multiple edges.


CANDIDATE D — RELATION-FAMILY-AWARE EMBEDDING

Predicate:

Node embedded only if it reaches active context through a short path (≤3 hops) where every relationship belongs to an approved semantic family.

Existing relationships sufficient: PARTIAL — the SituationRelationship enum covers all necessary types, but defining "families" requires additional rules not present in the current schema. The natural families are:

  • Option membership: contained_in, childIds
  • Decision consequence: may_cause, causes, affects
  • Decision dependency: depends_on (node array or edge)

Fixes 60B.12: YES — may_cause belongs to decision-consequence family.
False-compatibility risk: MEDIUM — defining families precisely enough to avoid over-inclusion requires explicit rule enumeration. The "short path" constraint partially mitigates this.
Genuine transition preserved: DEBATABLE — if contradiction edges cross into the allowed families through intermediate nodes, a genuine transition could be masked.


CANDIDATE E — PARENT OR DECISION-OPTION PATH (WINNER)

Predicate:

New unknown is structurally embedded in active context if EITHER: A. Its parentId/ancestor chain reaches a node with the current active pattern, OR B. It attaches to an option via may_cause / causes / affects edge, where that option is contained_in (directly or via childIds) the active decision unknown.

Fixes 60B.12: YES — both routes apply:

  • Route A: parentId chain connects client_retention → opt_relocate → n_relocation_decision (decision pattern ancestor).
  • Route B: may_cause edge to opt_relocate, which is contained_in the active decision unknown.

Semantic precision: HIGH — two explicit, semantically distinct routes with clear boundaries. Neither route alone is sufficient; together they cover the common structural patterns of embedded decision factors without enabling arbitrary connectivity.

Coverage: HIGH — covers all common embedding patterns: hierarchical nesting (parent chain) and edge-based attachment to decision-relevant options (decision-option path).

False-compatibility risk: MEDIUM — the combined predicate catches more cases than A alone, but each route has independently well-defined semantic boundaries. The key constraint is that Route B requires the target option to be directly contained_in a decision unknown (not just any node), preventing drift into weakly-connected regions of the graph.

Genuine transition preserved: YES — examining the test case at line 2486:

  • n-commercial-comparison-child has parentId → n-commercial-parent (decision).
  • Route A triggers (parent chain reaches decision ancestor).
  • BUT: comparison IS already allowed under decision per ALLOWED_NODE_PATTERNS. So intrinsic inference correctly returns "comparison", compatibility check passes (comparison is in the allowed list), and no structural embedding logic is needed.
  • The candidate does NOT change this outcome because it only modifies the compatibility decision path (when intrinsic pattern is incompatible), not the intrinsic pattern inference itself.
  • For a genuine transition where intrinsic text signals "diagnosis" inside a decision context (e.g., "What causes the revenue discrepancy?"), Route B would NOT trigger because there's no may_cause/causes/affects edge to an option — only parent-child containment. Route A would trigger but this is correct: the unknown IS structurally embedded in the decision, and normalizing it is the intended behavior of 60B.14's compatibility fallback.
  • The key distinction: genuine transitions are preserved by the ALLOWED_NODE_PATTERNS table (comparison stays disallowed under decision regardless of embedding), while the structural embedding predicate only affects the normalization decision when intrinsic inference produces an incompatible result — which indicates likely wording drift rather than pattern transition.

60B.12 WALKTHROUGH PER CANDIDATE

Candidate Embedded? Compatibility Result
A — Parent chain only YES ACCEPT (compatible via normalization)
B — Decision-option path YES (may_cause = SUFFICIENT) ACCEPT (compatible via normalization)
C — Any graph path YES ACCEPT (but too permissive in general)
D — Relation-family-aware YES (may_cause ∈ decision-consequence family) ACCEPT (compatible via normalization)
E — Parent OR decision-option YES (both routes apply) ACCEPT (compatible via normalization)

DECISION CRITERIA EVALUATION

Criterion A B C D E
1. Accepts 60B.12 client-retention unknown YES YES YES YES YES
2. Does not rely on keywords YES YES YES YES YES
3. Does not treat arbitrary connectivity as context ownership YES PARTIAL (needs path limit) NO PARTIAL (needs family rules) YES
4. Preserves genuine pattern transitions YES DEBATABLE NO DEBATABLE YES
5. Uses existing schema/relationships YES YES YES PARTIAL (family needs definition) YES
6. Is deterministic and provider-agnostic YES YES YES PARTIAL YES

WINNING MODEL

Choice: E — PARENT OR DECISION-OPTION PATH

Why:

  1. Candidate A alone is too narrow (misses edge-connected nodes).
  2. Candidate B is a strong runner-up but Route B's relationship-by-relationship analysis shows that not all incoming edges are sufficient — requiring additional disambiguation logic.
  3. Candidate C is too permissive for any production use.
  4. Candidate D requires inventing semantic family rules not present in the current schema, increasing implementation complexity.
  5. Candidate E provides two independent, semantically distinct routes with clear boundaries: the explicit parent-chain (already implemented in determineActiveReasoningPattern) and the direct-decision-option path (may_cause/causes/affects to option → contained_in → decision). Neither route alone is sufficient; together they cover all common embedding patterns without enabling arbitrary graph connectivity.

Exact structural-embedding predicate:

A new unresolved unknown X is embedded in active context Y if:

  1. Any ancestor in X's parentId chain has reasoning pattern Y, OR
  2. X connects via may_cause/causes/affects edge to node Z, and Z.parentId (direct) or Z.childIds contains a node with reasoning pattern Y.

Smallest implementation boundary: One conditional branch in assessReasoningPatternCompatibility (apply-proposal.js ~line 1897), reusing existing buildParentChain and checking edge relationships on the current graph without new traversals or schema changes.


IMPLEMENTATION READINESS

A — READY FOR BOUNDED IMPLEMENTATION

No unresolved design questions. The structural embedding predicate is fully defined using existing schema types and relationship semantics. The two routes (parent chain, decision-option path) map directly to existing data structures.


Production code changed: NO Prompt changed: NO Validator changed: NO (read-only analysis only) Schema changed: NO Tests changed: NO Ollama calls: 0 Live API calls: 0 Vitest run: NO Documentation updated: YES

Git status: clean (documentation commit pending)