feat(selector): 增加离线候选遍历与严格回放验证 Demo

- 新增 selector_candidate_demo,移除 provenance intent 后枚举候选 selector
- 对候选分支执行有界重建与严格 STEP 比较
- 仅在候选遍历完整且唯一 strict 通过时生成 selector 映射记录
- 增加 selector 候选搜索、预算限制和记录生成的测试
- 保持生产 selector resolver 不受 Demo 逻辑影响
- 更新 CADFS 能力台账,记录 IMPRINT 派生 profile 的 lineage selector 缺口
This commit is contained in:
2026-09-10 15:12:57 +08:00
parent d8fc2a9207
commit 994d06aaea
36 changed files with 9268 additions and 753 deletions
+101 -38
View File
@@ -20,6 +20,7 @@ working.
from __future__ import annotations
from copy import deepcopy
from dataclasses import dataclass, field
from pathlib import Path
from typing import Any
@@ -27,6 +28,7 @@ from . import executors # noqa: F401 (importing performs executor registration
from .capabilities import CapabilityAnalyzer, pattern_transform_blocker, sketch_ids_required_by_contract
# Historical private name still imported by the test suite.
from .executors.primitives import _execute_box # noqa: F401
from .executors.common import _selector_edges # noqa: F401
from .extents import (
_extent_reference,
_extent_vectors,
@@ -73,6 +75,9 @@ from .topology import (
SelectorResolution, TopologyDelta, TopologyDeltaRelation, TopologyRecord, TopologyRegistry,
)
# Historical private imports used by integration tests and local diagnostics.
_execute_node = execute_node
__all__ = [
"ALL_ATOMIC_IDS",
"EXECUTORS",
@@ -85,7 +90,10 @@ __all__ = [
"GeometryAdapter",
"RuntimeDiagnostic",
"RuntimeExecutionError",
"IncrementalCdslExecution",
"analyze_cdsl",
"prepare_cdsl_execution",
"finalize_cdsl_execution",
"execute_node",
"rebuild_cdsl",
]
@@ -101,8 +109,81 @@ def analyze_cdsl(cdsl: dict[str, Any]):
return analyzer.analyze(resolved, sketch_errors=sketch_errors)
def rebuild_cdsl(cdsl: dict[str, Any], out_step: Path, *, strict: bool = True) -> dict[str, Any]:
"""Rebuild CDSL through session-scoped atomic executors only."""
def _preflight_error(analysis: Any) -> ValueError | None:
if analysis.runtime_eligible:
return None
first = next((result for result in analysis.feature_results if not result.executable), None)
if first is None:
return ValueError(analysis.document_blockers[0].code)
if any(blocker.code == "unknown_atomic" for blocker in first.blockers):
return ValueError(f"unsupported atomic_id: {first.atomic_id}")
detail = "; ".join(blocker.code for blocker in first.blockers)
return ValueError(f"Feature {first.feature_id} is not runtime eligible: {detail}")
def _execution_diagnostic(
error: Exception,
node: FeaturePlanNode,
session: ExecutionSession,
) -> RuntimeDiagnostic:
failed_resolution = next(
(item for item in reversed(session.selector_resolutions) if item["status"] != "resolved"), None,
)
if isinstance(error, FeatureExecutionError):
return RuntimeDiagnostic(error.code, str(error), feature_id=node.feature_id, detail=error.detail)
if failed_resolution and failed_resolution.get("diagnostic"):
diagnostic = failed_resolution["diagnostic"]
return RuntimeDiagnostic(
diagnostic["code"], diagnostic["message"], feature_id=node.feature_id,
detail=diagnostic.get("detail") or {},
)
return RuntimeDiagnostic("execution_failed", str(error), feature_id=node.feature_id)
@dataclass
class IncrementalCdslExecution:
"""One prepared CDSL replay with feature-at-a-time execution.
CADFS selector binding consumes this object before each feature executes.
It therefore observes the exact session topology snapshots generated by
the one real kernel replay rather than rebuilding a growing prefix for
every selector. The generic runtime also uses it through ``rebuild_cdsl``.
"""
resolved_cdsl: dict[str, Any]
analysis: Any
session: ExecutionSession
diagnostics: list[RuntimeDiagnostic] = field(default_factory=list)
next_index: int = 0
def execute_next(self, *, strict: bool = True) -> FeatureResult | None:
if self.next_index >= len(self.analysis.plan):
raise ValueError("CDSL execution plan is already complete")
node = self.analysis.plan[self.next_index]
preflight = self.analysis.feature_results[self.next_index]
self.next_index += 1
if not preflight.executable:
self.diagnostics.extend(preflight.blockers)
if strict:
detail = "; ".join(blocker.code for blocker in preflight.blockers)
raise ValueError(f"Feature {node.feature_id} is not runtime eligible: {detail}")
return None
try:
return execute_node(node, self.session)
except Exception as error:
diagnostic = _execution_diagnostic(error, node, self.session)
self.diagnostics.append(diagnostic)
if strict:
raise RuntimeExecutionError(diagnostic, list(self.session.selector_resolutions)) from error
return None
def execute_all(self, *, strict: bool = True) -> None:
while self.next_index < len(self.analysis.plan):
self.execute_next(strict=strict)
def prepare_cdsl_execution(cdsl: dict[str, Any]) -> IncrementalCdslExecution:
"""Resolve CDSL once and return a reusable sequential execution session."""
sketch_errors: dict[str, str] = {}
resolved = resolve_required_sketches(
deepcopy(cdsl), sketch_ids_required_by_contract(cdsl), errors=sketch_errors,
@@ -110,45 +191,16 @@ def rebuild_cdsl(cdsl: dict[str, Any], out_step: Path, *, strict: bool = True) -
analysis = CapabilityAnalyzer(atomic_ids=EXECUTORS, profile_types=CORE_SHAPE_GENERATORS).analyze(
resolved, sketch_errors=sketch_errors,
)
if strict and not analysis.runtime_eligible:
first = next((result for result in analysis.feature_results if not result.executable), None)
if first is None:
raise ValueError(analysis.document_blockers[0].code)
if any(blocker.code == "unknown_atomic" for blocker in first.blockers):
raise ValueError(f"unsupported atomic_id: {first.atomic_id}")
detail = "; ".join(blocker.code for blocker in first.blockers)
raise ValueError(f"Feature {first.feature_id} is not runtime eligible: {detail}")
session = ExecutionSession(
sketches={str(sketch.get("id")): sketch for sketch in (resolved.get("geometry") or {}).get("sketches") or []},
nodes={node.feature_id: node for node in analysis.plan},
)
diagnostics: list[RuntimeDiagnostic] = []
for node, preflight in zip(analysis.plan, analysis.feature_results):
if not preflight.executable:
diagnostics.extend(preflight.blockers)
if strict:
break
continue
try:
execute_node(node, session)
except Exception as error:
failed_resolution = next(
(item for item in reversed(session.selector_resolutions) if item["status"] != "resolved"), None,
)
diagnostic = (
RuntimeDiagnostic(error.code, str(error), feature_id=node.feature_id, detail=error.detail)
if isinstance(error, FeatureExecutionError)
else
RuntimeDiagnostic(
failed_resolution["diagnostic"]["code"], failed_resolution["diagnostic"]["message"],
feature_id=node.feature_id, detail=failed_resolution["diagnostic"].get("detail") or {},
)
if failed_resolution and failed_resolution.get("diagnostic")
else RuntimeDiagnostic("execution_failed", str(error), feature_id=node.feature_id)
)
diagnostics.append(diagnostic)
if strict:
raise RuntimeExecutionError(diagnostic, list(session.selector_resolutions)) from error
return IncrementalCdslExecution(resolved, analysis, session)
def finalize_cdsl_execution(execution: IncrementalCdslExecution, out_step: Path) -> dict[str, Any]:
"""Export the current executable checkpoint from an incremental replay."""
session = execution.session
output = session.body
surface_geometry: dict[str, Any] | None = None
if output is None:
@@ -177,8 +229,19 @@ def rebuild_cdsl(cdsl: dict[str, Any], out_step: Path, *, strict: bool = True) -
"surface_face_count": int(surface_geometry["face_count"]) if surface_geometry is not None else 0,
"surface_area_mm2": float(surface_geometry["area_mm2"]) if surface_geometry is not None else 0.0,
"feature_results": [result.as_dict() for result in session.results.values()],
"runtime_diagnostics": [diagnostic.as_dict() for diagnostic in diagnostics],
"runtime_diagnostics": [diagnostic.as_dict() for diagnostic in execution.diagnostics],
"topology_records": [record.public_dict() for record in session.topology.records()],
"topology_deltas": list(session.topology.topology_deltas()),
"selector_resolution": session.selector_resolutions,
}
def rebuild_cdsl(cdsl: dict[str, Any], out_step: Path, *, strict: bool = True) -> dict[str, Any]:
"""Rebuild CDSL through session-scoped atomic executors only."""
execution = prepare_cdsl_execution(cdsl)
if strict:
error = _preflight_error(execution.analysis)
if error is not None:
raise error
execution.execute_all(strict=strict)
return finalize_cdsl_execution(execution, out_step)