docs: record bounded structural context admission
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user