orchestrata_ultimate.refactor.codemod.review_engine
Reference › orchestrata_ultimate › refactor › codemod › review_engine
The in-memory review engine that workspace runs over a mutated forest before it writes anything. The daemon server and scripts.codemod also use it. It combines the catalogue, the check implementations, the context and the Prolog pass from review.
ReviewPhaseRunner.run_phase runs one phase's checks over a set of modules: phase 1 runs one task per file on a thread pool, phase 2 walks the files in order after it so graph reads are not interleaved. A failing check raises, so a crashed review is never treated as a clean one. InMemoryReviewEngine is configured with a registry (the default catalogue is imported lazily, because the verification checks it pulls in are numerous), an optional Prolog pass, a baseline and include_phase3. review_detailed runs the checks on the mutated modules and returns a ReviewOutcome of introduced and legacy findings, then appends the Prolog findings; review returns the introduced findings only. The default baseline is delta (ADR-0073): the same checks run over the original trees, and a finding counts as introduced only when it is absent there, matched on path, rule, a message with line numbers removed (_line_free) and the stripped line text. Findings already present are returned as legacy. The absolute baseline reports every finding of the mutated modules, and any other value raises ValueError.
_shared and _context build the ReviewContext for each file, including the dependency names declared in pyproject.toml (_declared_dependencies) and the banned registry. _top_level, _sibling_name and _is_test_path decide whether an import is local to the importer's root. without_phase3 returns a copy that skips the Prolog pass.
At a glance
| Source | src/orchestrata_ultimate/refactor/codemod/review_engine.py |
| Lines of code | 521 |
| Classes | 4 |
| Functions | 7 |
| Imports (internal) | orchestrata_ultimate.core.base.traces, orchestrata_ultimate.refactor.codemod.report, orchestrata_ultimate.refactor.codemod.review, orchestrata_ultimate.refactor.codemod.review_catalogue, orchestrata_ultimate.refactor.codemod.review_checks, orchestrata_ultimate.refactor.codemod.review_context, orchestrata_ultimate.refactor.ctok |
| Imported by | orchestrata_ultimate.refactor.codemod, orchestrata_ultimate.refactor.codemod.server, orchestrata_ultimate.refactor.codemod.workspace, scripts.codemod |
| Tests that import it | tests/refactor/codemod/test_review_checks.py, tests/refactor/codemod/test_review_engine.py, tests/refactor/codemod/test_review_engine_commit_wiring.py |
Class diagram
Dependency diagram
API
Classes
ReviewOutcome (dataclass)
Decorators: traces(spec='110', story='US-110-004', reqs=['REQ-110-033', 'REQ-110-035']), dataclass(frozen=True, slots=True) · Line 60
The two finding sets of one review (ADR-0073).
| Attribute | Type | Default |
|---|---|---|
introduced |
tuple[Finding, ...] |
|
legacy |
tuple[Finding, ...] |
() |
ReviewPhaseRunner
Decorators: traces(spec='110', story='US-110-004', reqs=['REQ-110-035']) · Line 75
Run one phase's checks over a set of modules.
| Method | Signature | Summary |
|---|---|---|
__init__ |
__init__(registry: CheckRegistry, max_workers: int | None = None) -> None |
Bind the registry and the phase-1 worker count. |
run_phase |
run_phase(phase: Literal[1, 2], modules: Mapping[str, LosslessModule], ctx_factory: Callable[[str], ReviewContext]) -> list[Finding] |
Run every check of phase over every module. |
_run_file |
_run_file(checks: tuple[ReviewCheck, ...], path: str, module: LosslessModule, ctx: ReviewContext) -> list[Finding] |
Every check of the phase over one module. |
InMemoryReviewEngine
Decorators: traces(spec='110', story='US-110-004', reqs=['REQ-110-033', 'REQ-110-034', 'REQ-110-035']) · Line 151
The 40-check review over the mutated forest (a ReviewPass).
| Attribute | Type | Default |
|---|---|---|
name |
str |
'InMemoryReviewEngine' |
| Method | Signature | Summary |
|---|---|---|
__init__ |
__init__(registry: CheckRegistry | None = None, prolog: ReviewPass | None = None, baseline: _Baseline = 'delta', include_phase3: bool = True, max_workers: int | None = None) -> None |
Configure the engine. |
without_phase3 |
without_phase3() -> InMemoryReviewEngine |
A copy that skips the Prolog pass (the caller already runs one). |
review |
review(ws: ReviewableWorkspace, changes: ChangeSet) -> list[Finding] |
Review the mutated modules of changes. |
review_detailed |
review_detailed(ws: ReviewableWorkspace, changes: ChangeSet) -> ReviewOutcome |
Review the mutated modules and keep the legacy findings (ADR-0073). |
_run_checks |
_run_checks(ws: ReviewableWorkspace, modules: Mapping[str, LosslessModule], forest: Mapping[str, LosslessModule]) -> list[Finding] |
Phases 1 and 2 over modules, with forest on the context. |
_shared |
_shared(ws: ReviewableWorkspace, forest: Mapping[str, LosslessModule]) -> dict[str, frozenset[str]] |
The per-review facts every file's context shares. |
_context |
_context(ws: ReviewableWorkspace, path: str, forest: Mapping[str, LosslessModule], shared: Mapping[str, frozenset[str]]) -> ReviewContext |
The context for one file of the review. |
_declared_dependencies staticmethod |
_declared_dependencies(root: Path) -> frozenset[str] |
Dependency names from the workspace's pyproject.toml. |
_delta staticmethod |
_delta(mutated: list[Finding], original: list[Finding], mutated_trees: Mapping[str, LosslessModule], original_trees: Mapping[str, LosslessModule]) -> tuple[list[Finding], list[Finding]] |
Split mutated into (introduced, legacy) against original. |
_LineTexts
Line 450
Stripped source line of a finding, read from its own tree.
| Method | Signature | Summary |
|---|---|---|
__init__ |
__init__(trees: Mapping[str, LosslessModule]) -> None |
|
text |
text(finding: Finding) -> str |
The stripped text of finding.line in finding.path. |
Functions
| Function | Signature | Summary |
|---|---|---|
_top_level |
_top_level(path: str) -> str |
The top-level name a forest path contributes to every importer. |
_sibling_name |
_sibling_name(path: str) -> str | None |
The bare import name a file directly under a sibling root contributes. |
_is_test_path |
_is_test_path(path: str) -> bool |
Whether path names a test file. |
_line_free |
_line_free(message: str) -> str |
message without the line numbers it embeds. |
_requirement_name |
_requirement_name(spec: str) -> str |
Normalised distribution name of one dependency specifier. |
_declared_specs |
_declared_specs(data: Mapping[str, Any]) -> list[str] |
Every dependency specifier a parsed pyproject.toml declares. |
_import_names_of |
_import_names_of(declared: set[str]) -> set[str] |
Import names the declared distributions provide (protobuf -> google). |
Source
"""SPEC-110 FR-012 -- the in-memory review engine.
``InMemoryReviewEngine`` runs the 40-check catalogue over the MUTATED
forest in three phases (REQ-110-035): phase 1 is the file-local structural
checks, run in parallel per file; phase 2 is the correctness and
test-isolation checks, run after phase 1 with the workspace's
``CodeIntelligenceGraph`` on the context; phase 3 is the existing
``PrologSemanticReview``. Findings come only from the mutated modules'
``ast`` overlay and token streams (REQ-110-034): the engine never re-reads
source from disk.
``baseline='delta'`` (the default, ADR-0073) reports as findings only those
the pass introduced, so an error finding aborts the commit (ERR-110-002)
only when the change introduced it; the findings the original trees already
carried come back separately as legacy findings and never veto.
``baseline='absolute'`` (the opt-in clean-slate gate) reports every finding
of the mutated modules.
"""
from __future__ import annotations
import os
import re
import tomllib
from collections import Counter
from collections.abc import Callable, Mapping
from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass
from importlib.metadata import packages_distributions
from pathlib import Path
from typing import TYPE_CHECKING, Any, Literal, cast
from orchestrata_ultimate.core.base.traces import traces
from orchestrata_ultimate.refactor.codemod.report import ChangeSet, Finding
from orchestrata_ultimate.refactor.codemod.review import (
PrologSemanticReview,
ReviewPass,
_banned_libraries,
)
from orchestrata_ultimate.refactor.codemod.review_catalogue import (
CheckRegistry,
ReviewCheck,
)
from orchestrata_ultimate.refactor.codemod.review_context import (
_SIBLING_ROOTS,
ReviewableWorkspace,
ReviewContext,
)
if TYPE_CHECKING:
from orchestrata_ultimate.refactor.ctok import LosslessModule
_MAIN_FILES = frozenset({"cli.py", "__main__.py", "main.py"})
_DIST_NAME = re.compile(r"\s*([A-Za-z0-9][A-Za-z0-9._-]*)")
_Baseline = Literal["absolute", "delta"]
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033", "REQ-110-035"])
@dataclass(frozen=True, slots=True)
class ReviewOutcome:
"""The two finding sets of one review (ADR-0073).
Attributes:
introduced: Findings the change introduced (every finding under the
``absolute`` baseline); the only set that can veto a commit.
legacy: Findings the original trees already carried, reported but
never vetoing; always empty under the ``absolute`` baseline.
"""
introduced: tuple[Finding, ...]
legacy: tuple[Finding, ...] = ()
@traces(spec="110", story="US-110-004", reqs=["REQ-110-035"])
class ReviewPhaseRunner:
"""Run one phase's checks over a set of modules.
Phase 1 fans out one task per file; phase 2 walks the files in order so
its graph reads are not interleaved.
"""
@traces(spec="110", story="US-110-004", reqs=["REQ-110-035"])
def __init__(self, registry: CheckRegistry, max_workers: int | None = None) -> None:
"""Bind the registry and the phase-1 worker count.
Args:
registry: Supplies each phase's checks.
max_workers: Phase-1 pool size; the CPU count when ``None``.
"""
self._registry = registry
self._max_workers = max_workers
@traces(spec="110", story="US-110-004", reqs=["REQ-110-035"])
def run_phase(
self,
phase: Literal[1, 2],
modules: Mapping[str, LosslessModule],
ctx_factory: Callable[[str], ReviewContext],
) -> list[Finding]:
"""Run every check of ``phase`` over every module.
Args:
phase: 1 (parallel per file) or 2 (after phase 1).
modules: Forest-relative path -> module, in report order.
ctx_factory: Builds the context for one path.
Returns:
Findings in module order, then check order; a failing check
raises (a crashed review is not a clean one).
"""
checks = self._registry.checks_for_phase(phase)
if not checks or not modules:
return []
paths = list(modules)
workers = min(len(paths), self._max_workers or os.cpu_count() or 1)
if phase == 1 and workers > 1:
with ThreadPoolExecutor(max_workers=workers) as pool:
batches = list(
pool.map(
lambda path: self._run_file(
checks, path, modules[path], ctx_factory(path)
),
paths,
)
)
else:
batches = [
self._run_file(checks, path, modules[path], ctx_factory(path))
for path in paths
]
return [finding for batch in batches for finding in batch]
@traces(spec="110", story="US-110-004", reqs=["REQ-110-035"])
def _run_file(
self,
checks: tuple[ReviewCheck, ...],
path: str,
module: LosslessModule,
ctx: ReviewContext,
) -> list[Finding]:
"""Every check of the phase over one module."""
findings: list[Finding] = []
for check in checks:
findings.extend(check.run(module, ctx))
return findings
@traces(
spec="110", story="US-110-004", reqs=["REQ-110-033", "REQ-110-034", "REQ-110-035"]
)
class InMemoryReviewEngine:
"""The 40-check review over the mutated forest (a ``ReviewPass``)."""
name: str = "InMemoryReviewEngine"
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033", "REQ-110-035"])
def __init__(
self,
registry: CheckRegistry | None = None,
prolog: ReviewPass | None = None,
baseline: _Baseline = "delta",
include_phase3: bool = True,
max_workers: int | None = None,
) -> None:
"""Configure the engine.
Args:
registry: The catalogue; ``default_registry()`` when ``None``.
prolog: The phase-3 pass; a fresh ``PrologSemanticReview`` per
review when ``None``.
baseline: ``delta`` (default, ADR-0073) reports only the
findings the change introduced, matched on path, rule and
line-free message; ``absolute`` reports every finding of the
mutated modules (the clean-slate gate).
include_phase3: Run the Prolog pass after phases 1 and 2.
max_workers: Phase-1 pool size.
Raises:
ValueError: ``baseline`` is neither ``absolute`` nor ``delta``.
"""
if baseline not in ("absolute", "delta"):
raise ValueError(f"baseline must be 'absolute' or 'delta': {baseline!r}")
if registry is None:
# Deferred on purpose: review_checks pulls the verification review
# checks (103 eager modules over six packages, measured
# 2026-10-08). An eager import here broke the deployed
# codemod-daemon's import smoke on 2026-10-08 (ship of 3bb5319df)
# while the tools deploy vendored a hand-written subtree list; the
# list is computed and gate-pinned since WI-DEPLOY
# (deploy/tools-vendor-manifest.txt, tests/deploy/
# test_tools_vendor_manifest.py), so the deployed daemon resolves
# this import. It stays lazy so the daemon's eager closure remains
# one module (scripts/tools_import_closure.py --eager) and the
# package imports wherever a catalogue is injected.
from orchestrata_ultimate.refactor.codemod.review_checks import (
default_registry,
)
registry = default_registry()
self._registry = registry
self._prolog = prolog
self._baseline: _Baseline = baseline
self._include_phase3 = include_phase3
self._max_workers = max_workers
self._runner = ReviewPhaseRunner(self._registry, max_workers)
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033", "REQ-110-035"])
def without_phase3(self) -> InMemoryReviewEngine:
"""A copy that skips the Prolog pass (the caller already runs one)."""
return InMemoryReviewEngine(
registry=self._registry,
prolog=self._prolog,
baseline=self._baseline,
include_phase3=False,
max_workers=self._max_workers,
)
@traces(
spec="110",
story="US-110-004",
reqs=["REQ-110-033", "REQ-110-034", "REQ-110-035"],
)
def review(self, ws: ReviewableWorkspace, changes: ChangeSet) -> list[Finding]:
"""Review the mutated modules of ``changes``.
Args:
ws: The workspace the changes were computed against.
changes: The pass output; each entry's ``mutated_tree`` is read.
Returns:
The introduced findings of :meth:`review_detailed`: phase-1
findings, phase-2 findings, then phase-3 findings.
"""
return list(self.review_detailed(ws, changes).introduced)
@traces(
spec="110",
story="US-110-004",
reqs=["REQ-110-033", "REQ-110-034", "REQ-110-035"],
)
def review_detailed(
self, ws: ReviewableWorkspace, changes: ChangeSet
) -> ReviewOutcome:
"""Review the mutated modules and keep the legacy findings (ADR-0073).
Args:
ws: The workspace the changes were computed against.
changes: The pass output; each entry's ``mutated_tree`` is read.
Returns:
The introduced findings (phase 1, phase 2, then phase 3) and, under
the ``delta`` baseline, the legacy findings the original trees
already carried; ``legacy`` is empty under ``absolute``.
"""
mutated = {entry.path: entry.mutated_tree for entry in changes.entries}
findings = self._run_checks(ws, mutated, {**ws.forest, **mutated})
legacy: list[Finding] = []
if self._baseline == "delta":
original = {entry.path: entry.original_tree for entry in changes.entries}
findings, legacy = self._delta(
findings,
self._run_checks(ws, original, {**ws.forest, **original}),
mutated,
original,
)
if self._include_phase3:
prolog = (
self._prolog if self._prolog is not None else PrologSemanticReview()
)
# review.py's ReviewPass names a forward-reference stand-in for
# the workspace; the real one is passed through unchanged.
findings.extend(prolog.review(cast("Any", ws), changes))
return ReviewOutcome(introduced=tuple(findings), legacy=tuple(legacy))
@traces(spec="110", story="US-110-004", reqs=["REQ-110-035"])
def _run_checks(
self,
ws: ReviewableWorkspace,
modules: Mapping[str, LosslessModule],
forest: Mapping[str, LosslessModule],
) -> list[Finding]:
"""Phases 1 and 2 over ``modules``, with ``forest`` on the context."""
shared = self._shared(ws, forest)
def ctx_factory(path: str) -> ReviewContext:
return self._context(ws, path, forest, shared)
findings = self._runner.run_phase(1, modules, ctx_factory)
findings.extend(self._runner.run_phase(2, modules, ctx_factory))
return findings
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033"])
def _shared(
self, ws: ReviewableWorkspace, forest: Mapping[str, LosslessModule]
) -> dict[str, frozenset[str]]:
"""The per-review facts every file's context shares."""
paths = set(forest) | {path for path, _ in ws.unparsable}
return {
"project_modules": frozenset(_top_level(path) for path in paths),
"sibling_modules": frozenset(
name for path in paths if (name := _sibling_name(path)) is not None
),
"workspace_files": frozenset(paths),
"declared_deps": self._declared_dependencies(ws.root),
"banned_libraries": _banned_libraries(),
}
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033"])
def _context(
self,
ws: ReviewableWorkspace,
path: str,
forest: Mapping[str, LosslessModule],
shared: Mapping[str, frozenset[str]],
) -> ReviewContext:
"""The context for one file of the review.
Only a module under a sibling-import root may import a sibling by bare
name (``scripts/`` is not on ``sys.path`` for ``src/``), so only such a
module's ``project_modules`` carry the sibling names.
"""
name = os.path.basename(path)
project_modules = shared["project_modules"]
if path.split("/")[0] in _SIBLING_ROOTS:
project_modules = project_modules | shared["sibling_modules"]
return ReviewContext(
path=path,
forest=forest,
cig=ws.cig,
project_modules=project_modules,
workspace_files=shared["workspace_files"],
declared_deps=shared["declared_deps"],
root=ws.root,
is_test=_is_test_path(path),
is_main_file=name in _MAIN_FILES,
banned_libraries=shared["banned_libraries"],
include_roots=ws.include_roots,
)
@staticmethod
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033"])
def _declared_dependencies(root: Path) -> frozenset[str]:
"""Dependency names from the workspace's ``pyproject.toml``.
Reads every place a dependency is declared (see ``_declared_specs``)
and adds the import names the declared distributions provide, so an
import of ``google`` is declared by ``protobuf``. This is
configuration and installed-package metadata, not source: it is read
once per review by the engine, never by a check.
"""
try:
data = tomllib.loads((root / "pyproject.toml").read_text(encoding="utf-8"))
except OSError, tomllib.TOMLDecodeError:
return frozenset()
declared = {
name for name in map(_requirement_name, _declared_specs(data)) if name
}
return frozenset(declared | _import_names_of(declared))
@staticmethod
@traces(spec="110", story="US-110-004", reqs=["REQ-110-033"])
def _delta(
mutated: list[Finding],
original: list[Finding],
mutated_trees: Mapping[str, LosslessModule],
original_trees: Mapping[str, LosslessModule],
) -> tuple[list[Finding], list[Finding]]:
"""Split ``mutated`` into (introduced, legacy) against ``original``.
Matched on (path, rule, line-free message, stripped text of the
finding's line) with multiplicity, never the line number: an edit
above a legacy finding shifts it (and the line number the reused
checks embed in the message) without introducing it. Each side reads
the line text from its own tree, so an in-place edit of a line that
already carries a content-free finding (the secret check's message
names no content) is an introduced finding, not a legacy one.
"""
mutated_lines = _LineTexts(mutated_trees)
original_lines = _LineTexts(original_trees)
known = Counter(
(f.path, f.rule, _line_free(f.message), original_lines.text(f))
for f in original
)
introduced: list[Finding] = []
legacy: list[Finding] = []
for finding in mutated:
key = (
finding.path,
finding.rule,
_line_free(finding.message),
mutated_lines.text(finding),
)
if known[key] > 0:
known[key] -= 1
legacy.append(finding)
else:
introduced.append(finding)
return introduced, legacy
def _top_level(path: str) -> str:
"""The top-level name a forest path contributes to every importer.
``src/<pkg>/...`` contributes ``<pkg>``; any other path contributes its
first component (the root's own name). The bare names a sibling-import
root contributes to its own members are ``_sibling_name``'s.
"""
parts = path.removesuffix(".py").split("/")
if parts[0] == "src" and len(parts) > 1:
return parts[1]
return parts[0]
def _sibling_name(path: str) -> str | None:
"""The bare import name a file directly under a sibling root contributes.
Under a sibling-import root (``scripts``, ``tests``, ``claude``) a file
directly under the root contributes its stem and a package directory its
own name, because those trees are put on ``sys.path`` and imported by bare
name (the rule ``check-deps`` applies). The root's own ``__init__.py``,
nested stems below a package and every other path contribute nothing.
"""
parts = path.removesuffix(".py").split("/")
if parts[0] not in _SIBLING_ROOTS or len(parts) < 2 or parts[1:] == ["__init__"]:
return None
return parts[1]
def _is_test_path(path: str) -> bool:
"""Whether ``path`` names a test file.
A test file has a ``tests``/``test`` directory component in its
repo-relative path, or is a ``conftest.py``. A ``test_*.py`` basename
under ``src/`` or ``scripts/`` is production (``core/threading/
test_scheduler.py`` is a scheduler, not a test).
"""
parts = path.split("/")
return parts[-1] == "conftest.py" or any(
part in ("tests", "test") for part in parts[:-1]
)
# ``L12: msg`` / ``L12 msg`` leads, ``(line 7)`` tokens and bare ``line 9``
# references: the three shapes the reused ``check_*`` functions embed.
_LEADING_LINE = re.compile(r"^L\d+(?::|\s)\s*")
_PAREN_LINE = re.compile(r"\s*\(line \d+\)")
_BARE_LINE = re.compile(r"\bline \d+\b")
class _LineTexts:
"""Stripped source line of a finding, read from its own tree.
The lines of each module are split once, on first use; a finding with no
line, a line out of range or a path outside the trees reads ``""``.
"""
def __init__(self, trees: Mapping[str, LosslessModule]) -> None:
self._trees = trees
self._lines: dict[str, list[str]] = {}
def text(self, finding: Finding) -> str:
"""The stripped text of ``finding.line`` in ``finding.path``."""
module = self._trees.get(finding.path)
if module is None or finding.line is None:
return ""
lines = self._lines.get(finding.path)
if lines is None:
lines = module.stream.source.decode("utf-8", errors="replace").split("\n")
self._lines[finding.path] = lines
if not 1 <= finding.line <= len(lines):
return ""
return lines[finding.line - 1].strip()
def _line_free(message: str) -> str:
"""``message`` without the line numbers it embeds.
Delta matching compares messages across the original and mutated trees;
an edit above a legacy finding moves its line number into the message,
and the moved finding is still the same finding.
"""
text = _LEADING_LINE.sub("", message)
text = _PAREN_LINE.sub("", text)
text = _BARE_LINE.sub("line", text)
return " ".join(text.split())
def _requirement_name(spec: str) -> str:
"""Normalised distribution name of one dependency specifier."""
match = _DIST_NAME.match(spec)
return re.sub(r"[-_.]+", "_", match.group(1)).lower() if match else ""
def _declared_specs(data: Mapping[str, Any]) -> list[str]:
"""Every dependency specifier a parsed ``pyproject.toml`` declares.
``[project] dependencies``, every ``[project.optional-dependencies]``
group, ``[dependency-groups]`` (string entries; include tables are not
specifiers) and ``[tool.uv] dev-dependencies``.
"""
project = data.get("project", {})
specs: list[str] = list(project.get("dependencies", []))
for group in (project.get("optional-dependencies", {}) or {}).values():
specs.extend(group)
for group in (data.get("dependency-groups", {}) or {}).values():
specs.extend(spec for spec in group if isinstance(spec, str))
specs.extend(data.get("tool", {}).get("uv", {}).get("dev-dependencies", []))
return specs
def _import_names_of(declared: set[str]) -> set[str]:
"""Import names the declared distributions provide (``protobuf`` -> ``google``).
The distribution -> import-name table is ``importlib.metadata``'s, the
same one ``scripts/serialize_codebase_ast.py check-deps`` consults.
"""
return {
module.lower()
for module, dists in packages_distributions().items()
if any(re.sub(r"[-_.]+", "_", d).lower() in declared for d in dists)
}