from __future__ import annotations from copy import deepcopy from pathlib import Path import re from typing import Any def _last_executable_prefix(error: Exception, output: Path) -> dict[str, Any] | None: """Export the checkpoint already produced by the failed live replay.""" execution = getattr(error, "incremental_execution", None) bound = getattr(error, "bound_cdsl", None) if execution is None or not isinstance(bound, dict): return None session = execution.session if not session.results or (session.body is None and not session.surface_members): return None from engine.cdsl_engine.runtime import finalize_cdsl_execution try: result = finalize_cdsl_execution(execution, output) except Exception: return None last_feature_id = next(reversed(session.results)) features = list(bound.get("features") or []) feature_count = next( (index + 1 for index, feature in enumerate(features) if feature.get("id") == last_feature_id), 0, ) if feature_count == 0: return None prefix = deepcopy(bound) prefix["features"] = features[:feature_count] return { "failed_feature_id": getattr(error, "failed_feature_id", None) or _failed_feature_id(error), "feature_count": feature_count, "last_feature_id": last_feature_id, "bound_cdsl": prefix, "result": result, } def _failed_feature_id(error: Exception) -> str | None: diagnostic = getattr(error, "diagnostic", None) feature_id = getattr(diagnostic, "feature_id", None) if isinstance(feature_id, str) and feature_id: return feature_id match = re.match(r"([^:\s]+): ", str(error)) return match.group(1) if match else None def rebuild_candidate(cdsl: dict[str, Any], output: Path) -> dict[str, Any]: from engine.cdsl_engine.runtime import analyze_cdsl, finalize_cdsl_execution from .selector_binding import bind_and_execute_candidate_selectors analysis = analyze_cdsl(cdsl) analysis_dict = analysis.as_dict() if hasattr(analysis, "as_dict") else {"runtime_eligible": analysis.runtime_eligible} if not analysis.runtime_eligible: return {"status": "runtime_ineligible", "analysis": analysis_dict} try: replay = bind_and_execute_candidate_selectors(cdsl) result = finalize_cdsl_execution(replay.execution, output) return { "status": "rebuilt", "analysis": analysis_dict, "selector_binding": replay.evidence, "bound_cdsl": replay.bound_cdsl, "result": result, } except Exception as exc: detail = {"type": type(exc).__name__, "message": str(exc)} if hasattr(exc, "selector_resolutions"): detail["selector_resolutions"] = exc.selector_resolutions prefix = _last_executable_prefix(exc, output) result = {"status": "rebuild_failed", "analysis": analysis_dict, "error": detail} bound = getattr(exc, "bound_cdsl", None) if isinstance(bound, dict): result["bound_cdsl"] = bound binding = getattr(exc, "selector_binding", None) if isinstance(binding, list): result["selector_binding"] = binding if prefix is not None: result["last_executable_prefix"] = prefix return result