docs: record bounded structural context admission

This commit is contained in:
2026-08-13 12:49:42 +01:00
parent d871a8c5c4
commit a7ca8d712d
2 changed files with 146 additions and 1 deletions
+13 -1
View File
@@ -140,6 +140,18 @@ Experiment 54N tested whether an interpretation disagreement can be judged for m
- `npx vitest run tests/graph/apply-proposal.test.js tests/graph/prompt-builder.test.js` → PASS (174/174) - `npx vitest run tests/graph/apply-proposal.test.js tests/graph/prompt-builder.test.js` → PASS (174/174)
- **Still unproven live:** the exact 60B.6 continuation case where the model selects the newly exposed client-retention factor and the final target preserves that same ready material unknown in a live run. - **Still unproven live:** the exact 60B.6 continuation case where the model selects the newly exposed client-retention factor and the final target preserves that same ready material unknown in a live run.
### 60B.19 bounded structural context admission
- The blocked 60B.16 implementation was removed from the **global compatibility path** after 60B.17 showed it caused 8 `apply-proposal` regressions.
- The structural fallback now runs only for **newly-added unresolved unknowns** at the **pre-mutation proposal boundary** inside `applyValidatedProposal()`.
- The context identity for that admission is the **pre-update `activeUnknownNodeId`**, not the post-update selected node.
- Route A = ancestor chain to the original active decision; Route B = `may_cause` / `causes` / `affects` to an option `contained_in` that original active decision.
- A local in-memory admitted-node set now preserves that same-turn admission through later compatibility checks without changing generic compatibility semantics for unrelated nodes.
- Bounded verification passed:
- `npx vitest run tests/graph/reasoning-context-compatibility.test.js` → PASS (14/14)
- `npx vitest run tests/graph/apply-proposal.test.js tests/graph/reasoning-context-compatibility.test.js` → PASS (96/96)
- **Still unproven live:** the exact 60B.12 client-retention continuation case under live model output.
### When This Knowledge-Management Phase Is Complete ### When This Knowledge-Management Phase Is Complete
Provisional criteria for review (all confirmed met by Experiment 38 cold-start test): Provisional criteria for review (all confirmed met by Experiment 38 cold-start test):
@@ -2824,7 +2836,7 @@ Experiment 60B.13 performed read-only architectural diagnosis of the 60B.12 kind
--- ---
Experiment 60B.14 performed read-only design analysis on whether a newly-created unresolved factor inside an active decision should inherit the decision's reasoning pattern rather than being classified mainly from its wording. **Classification: D — COMPATIBILITY FALLBACK.** The current architecture separates *active pattern determination* (which DOES use parent-chain traversal via `determineActiveReasoningPattern` and correctly yields "decision" for the 60B.12 node) from *node-intrinsic pattern inference* (which does NOT use that context — it runs standalone text analysis on the node's label/description only). This separation is the root cause: the active pattern correctly walks up to find "decision" in the decision unknown, but the compatibility check re-runs standalone inference on the new node and gets "diagnosis" from its diagnostic-style wording ("will our largest client leave"). The smallest correct fix preserves intrinsic text analysis as primary signal but adds a normalization fallback: when inferred node pattern is incompatible with active pattern AND the node's graph position (parentId, edges) places it structurally within that active context, reinterpret using the active pattern rather than rejecting. This requires no new schema, no new keywords, and preserves genuine pattern transitions (the intrinsic inference still returns diagnosis; only the compatibility decision changes). Experiment 60B.14 performed read-only design analysis on whether a newly-created unresolved factor inside an active decision should inherit the decision's reasoning pattern rather than being classified mainly from its wording. **Classification: D — COMPATIBILITY FALLBACK.** The current architecture separates _active pattern determination_ (which DOES use parent-chain traversal via `determineActiveReasoningPattern` and correctly yields "decision" for the 60B.12 node) from _node-intrinsic pattern inference_ (which does NOT use that context — it runs standalone text analysis on the node's label/description only). This separation is the root cause: the active pattern correctly walks up to find "decision" in the decision unknown, but the compatibility check re-runs standalone inference on the new node and gets "diagnosis" from its diagnostic-style wording ("will our largest client leave"). The smallest correct fix preserves intrinsic text analysis as primary signal but adds a normalization fallback: when inferred node pattern is incompatible with active pattern AND the node's graph position (parentId, edges) places it structurally within that active context, reinterpret using the active pattern rather than rejecting. This requires no new schema, no new keywords, and preserves genuine pattern transitions (the intrinsic inference still returns diagnosis; only the compatibility decision changes).
--- ---
+133
View File
@@ -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