# Experiment 60B.61 — Decision Remaining-Material-Factor Detection ## Status: PASSED ### Objective Answer: *Does the dedicated remaining-material-factor helper work correctly once malformed tests are repaired, without any broader applyValidatedProposal integration?* **Answer: YES.** ### Scope (bounded) Helper detection experiment only. No closure integration. ### Production code added (2 helpers + internal support) | Export | Role | |--------|------| | `hasRemainingMaterialFactors(decisionNodeId, graph)` | Public boolean — `true` if any unresolved unknown remains material to the decision | | `countRemainingMaterialFactors(decisionNodeId, graph)` | Count variant — used internally by `hasRemainingMaterialFactors`; kept as exported for potential future use | - **Set-based deduplication** of factor IDs across routes (no double-count) - **Decision self-count excluded** (`node.id === decisionNodeId`) - **Terminal statuses excluded**: `known`, `resolved`, `contradicted` - **Helper-only**. No integration into `applyValidatedProposal` return, no closure logic change. ### Supported Routes | Route | Relationship Path | |-------|-------------------| | A — hierarchy | `parentId` chain or `childIds` membership | | B — direct dependency | `depends_on` edge to decision | | C — consequence | unknown → `{affects,may_cause,causes}` → option → `contained_in` → decision | | D — containment | unknown → `contained_in` → option → `contained_in` → decision | ### Excluded (returns false) - Known / resolved / contraduted statuses - `supports` / `measures` weak links - Arbitrary non-approved connectivity (`other`) - The decision node itself - Non-unknown kind nodes (e.g., observations) ### Test Suite (14 cases in 60B.61 block) 1. Containment-only unresolved factor → **true** 2. Same factor resolved → **false** 3. `may_cause` option-linked factor → **true** 4. Valid direct `depends_on` factor → **true**; resolved → **false** 5. Hierarchy child factor → **true** 6. Supports / measures weak link → **false** 7. Decision node alone does not self-count → **false** 8. Another genuine unresolved hierarchy child remains → **true** 9. Status = known excluded → **false** 10. Status = contradicted excluded → **false** 11. Non-unknown kinds excluded → **false** 12. 60B.56 sufficiency (all factors resolved) → **false** 13. Arbitrary connectivity via `other` edge → **false** 14. Additional resolution state within Route B test → **false** ### Regression Preservation - **60B.43**: PASSED - **60B.11**: PASSED - **Pricing prerequisite-first**: PASSED ### Git Commits ``` feat(reasoning): detect remaining decision factors docs: record decision factor detection ``` WHAT IS NOW GUARANTEED --- The helper `hasRemainingMaterialFactors(decisionNodeId, graph)` correctly identifies unresolved material factors for a decision node across all four approved routes (A–D), with Set-based deduplication and proper terminal-status exclusion. No production behaviour outside the helper itself was changed. WHAT REMAINS OPEN --- Decision-sufficiency closure integration remains a separate next experiment. The helper detects but does not influence any decision-closure logic at this time.