experiment: define option factor representation contract

This commit is contained in:
2026-08-14 12:30:01 +01:00
parent 3d7f2cc3dd
commit 909edd1019
2 changed files with 407 additions and 0 deletions
+42
View File
@@ -3022,3 +3022,45 @@ Experiment 60B.48 was a read-only code-path and contract diagnosis of why 60B.47
Experiment 60B.56 was a live regression of negative customer-signing closure after the proposal-compatibility fix (54e2e21). **Classification: D — GRAPH CLOSES BUT CONVERSATION DOES NOT.** The enterprise-customer unknown resolved in place (unknown → resolved), negative meaning preserved ("customer will not sign" confirmed in resolution reason), zero addedNodes/edges, zero validation errors. However, `finalActiveUnknownNodeId = "n_product_launch_decision"` (non-null) and `finalSelectedQuestion` was non-null — the engine formulated a decision_threshold follow-up question ("What outcome would demonstrate enough value to justify launching?") targeting the parent decision node instead of closing it. The proposal-compatibility bug from 60B.47 is fixed (proposal accepted, HTTP 200), but the clean-closure contract (null → null when all dependencies resolve) remains unmet. `n_product_launch_decision` stays unknown despite having no remaining dependent unknowns — both options are known. One live Ollama call at qwen-claude:latest on http://192.168.1.111:11434. No production code changed. Full trace in docs/experiment-60b56.md.
Experiment 60B.58 was a read-only decision-sufficiency evidence map. **Classification: E — DUAL-SIGNAL CLOSURE REQUIRED.** Analysis of the existing topology confirmed that no single signal suffices for correct closure detection. The winning model is Candidate E: relationship-aware graph traversal PLUS user declaration, both required independently. Key findings: (1) Existing architecture captures factor→option edges but does not traverse them during closure propagation — only parentId/depends_on children are counted; (2) Self-counting of the decision node as its own unresolved child is inherent in `selectActiveUnknownCandidate` because it filters only kind+resolvedNodeIds, never status alone beyond terminal exclusion; (3) Extending the predicate to include `affects → option contained_in decision` traversal fixes both premature-closure and missed-closure without schema changes. Implementation readiness: B — one unresolved question remains: which exact relationship types (affects, may_cause, causes) qualify as "decision-relevant" for generic factors beyond those already defined by 60B.15. No production code changed. 0 Ollama calls. Pure code inspection + fixture analysis. Full trace in docs/experiment-60b58.md.
Experiment 60B.60 — Is containment under-specified or sufficient for unknown-to-option materiality?
Type: READ-ONLY DESIGN BOUNDARY EXPERIMENT
Status: COMPLETE
## Summary
60B.59 defined the winning relationship family as `parentId/childIds + depends_on + affects/may_cause/causes → option → contained_in → decision` and excluded `contained_in` alone because it expresses membership, not consequence/prerequisite.
The 60B.56 customer-signing factor uses exactly this pattern:
```
n_enterprise_customer_signing (unknown, status=unknown)
-> [contained_in] -> opt_launch_this_year (option)
-> [contained_in] -> n_product_launch_decision (decision)
```
This was not recognized as material by the winning sufficiency family.
## Key Finding: Containment is Sufficient When Combined with Unknown Kind + Status
The sufficiency check's purpose is to determine "is there an unresolved unknown about a specific option of this decision that could change which option is preferred?" For this purpose:
- **kind=unknown** already filters out non-decision-factors (observations, metrics, evidence)
- **status=unknown** already gates on unresolved state
- The contained_in edge answers "which option is this about?" definitively
- Adding a required consequence/prerequisite relationship would make sufficiency dependent on model-output variance
Evidence: 60B.20's live client-retention case used `may_cause`; 60B.56's fixture uses `contained_in`. Both represent genuinely material factors. The model does not deterministically choose one over the other. Sufficiency should not depend on which convention the model happened to select.
## Contract:
- `unknown -> contained_in -> option` (kind=unknown + status=unknown) = sufficient for sufficiency path C
- `unknown -> affects/may_cause/causes -> option -> contained_in -> decision` = sufficiency path B (existing)
- `parentId/childIds` = sufficiency path A (existing)
- `depends_on` edge to decision = sufficiency path D (existing)
## Production code changed: NO
Tests changed: NO
Prompt changed: NO
Schema changed: NO
Ollama calls: 0
Live API calls: 0
Vitest run: NO