experiment: diagnose resolution contract mismatch

This commit is contained in:
2026-08-14 09:51:12 +01:00
parent 59ededfe06
commit 998ff2fcb7
2 changed files with 275 additions and 0 deletions
+4
View File
@@ -3002,3 +3002,7 @@ Experiment 60B.46 reran the exact 60B.44 closure case through one bounded live u
---
Experiment 60B.47 tested whether resolving the customer-signing factor with a **negative** answer (opposite polarity to 60B.46) produces symmetric lifecycle closure. **Classification: G — DIFFERENT FIRST FAILURE.** The engine's semantic reasoning was correct: same customer factor (`n_enterprise_customer_signing`) identified, negative meaning accurately preserved (`userSupportedMeaning` captured "will not sign" + £700k revenue lost), same decision (`n_product_launch_decision`) targeted. However, the proposal was rejected at `proposal_compatibility` with HTTP 422 because the model included `n_product_launch_decision` in `updatedNodes` but omitted it from `resolvedUnknownNodeIds` — a structural inconsistency when resolving multiple unknowns in one turn. No graph mutation occurred. No new unknowns invented (zero addedNodes/edges). The semantic path is symmetric; the structural output contract is not yet symmetric under negative framing. One live Ollama call at qwen-claude:latest on http://192.168.1.111:11434. No production code changed.
---
Experiment 60B.48 was a read-only code-path and contract diagnosis of why 60B.47's negative closure produced `updatedNodes` with both nodes at status=resolved but omitted the decision node from `resolvedUnknownNodeIds`. **Classification: E — MULTIPLE FACTORS (deterministic normalisation gap primary, prompt gap secondary, model output variance as symptom).** Root cause identified in `reconcileResolutionSemantics()` at lib/graph/apply-proposal.js:312-370. The function reconciles only one direction (`resolvedUnknownNodeIds → updatedNodes`) but never adds a node from `updatedNodes` into `resolvedUnknownNodeIds`. The prompt contains no explicit rule mandating the bidirectional structural tie between `newStatus="resolved"` and `resolvedUnknownNodeIds` membership. Validator at line 364-367 catches the mismatch but does not auto-fix it (only reports error). **Minimum corrective boundary: B — deterministic normalisation.** Add every unknown node updated to resolved into `resolvedUnknownNodeIds` inside `reconcileResolutionSemantics()` before validation (~4 lines of code). This preserves positive closure, makes negative closure structurally valid, and does not weaken semantic validation. No production code changed. 0 Ollama calls. Pure code inspection. Full analysis in docs/experiment-60b48.md.