# Experiment 60B.19 — Bounded Structural Context Admission **Branch:** `feature/reasoning-context-compatibility-v0.28` **Date:** 2026-08-13 **Status:** COMPLETE **Type:** BOUNDED IMPLEMENTATION ## Objective Replace the blocked 60B.16 global reasoning-compatibility fallback with the 60B.18 boundary: - run structural context fallback only for **newly-added unresolved unknowns**; - run it only when the **full proposal is known but before graph mutation**; - use the **pre-update `activeUnknownNodeId`** as the decision-context identity; - preserve that same-turn admission through later validation without changing generic compatibility semantics for unrelated nodes. ## Why the global 60B.16 integration was removed 60B.17 established that the structural Route A / Route B predicate itself was useful, but its **global integration layer was too broad**. Applying fallback inside generic compatibility checks caused 8 `apply-proposal` regressions by changing behaviour for unrelated pre-existing and later-selected unknowns. The secondary defect was that later compatibility re-checks could lose the original decision-context identity and validate against the wrong active node. ## Implemented boundary Structural context fallback now runs only at the **pre-mutation proposal boundary**: - eligibility is limited to `proposal.addedNodes` where: - `kind === "unknown"` - `status !== "resolved"` - the original context identity is: - `situationGraph.activeUnknownNodeId` - the original context pattern is recovered from the **pre-update graph** - structural admission is only relevant when: - `activePattern === "decision"` No pre-existing unknowns, updated existing nodes, resolved nodes, or later-selected targets enter the fallback by scope. ## Route A / Route B ### Route A Admit a newly-added unresolved unknown when its `parentId` / ancestor chain reaches the original active decision context node. ### Route B Admit a newly-added unresolved unknown when: - `X --(may_cause | causes | affects)--> option Z` - `Z --contained_in--> active decision D` - `D.id === pre-update activeUnknownNodeId` ### Explicit non-qualifiers These do **not** establish Route B: - `supports` - `measures` - `depends_on` - arbitrary graph connectivity ## Local admitted-node tracking No schema field was added. Within `applyValidatedProposal()` only, the implementation now maintains a local in-memory set of structurally admitted node IDs for same-turn newly-added unresolved unknowns. That set is then threaded into later compatibility checks so the exact already-adjudicated diagnosis→decision mismatch is not rejected again during post-mutation selection/result validation. This does **not**: - rewrite intrinsic node pattern; - make the node universally compatible; - disable non-pattern validations; - change question targeting, scoring, materiality, prompt, or schema. ## Regression restoration Focused suite: - `npx vitest run tests/graph/reasoning-context-compatibility.test.js` → **PASS (14/14)** Combined bounded verification: - `npx vitest run tests/graph/apply-proposal.test.js tests/graph/reasoning-context-compatibility.test.js` → **PASS (96/96)** This restored the 8 60B.17 regressions by construction: - pre-existing unknowns no longer enter fallback; - later-selected 60B.11 fixtures no longer trigger fallback merely because they are chosen after mutation; - later compatibility re-checks now use the preserved original reasoning-context node identity instead of selected-child drift; - generic compatibility semantics remain unchanged outside the bounded same-turn admission class. ## What remains unproven Still unproven until the exact live regression is rerun: - the precise 60B.12 client-retention continuation case in a live end-to-end path where the model introduces the factor and the final selected target preserves that same ready material unknown. ## Production code changed YES — `lib/graph/apply-proposal.js` ## Tests changed YES — `tests/graph/reasoning-context-compatibility.test.js` ## Prompt changed NO ## Schema changed NO ## Question targeting changed NO ## Materiality changed NO ## Selection scoring changed NO ## Ollama calls 0 ## Live API calls 0