core_engine_classify.py
2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
"""05 §5.8 / U-035: path-based classification of whether a self-target
change touches "core engine" territory -- `.claude/agents/*.md` identity
files, Graph Engine scheduler/executor source (`src/*.py`), or 01-M's own
schema (`src/schema.py`, itself a `src/*.py` file so already covered).
Deliberately NOT the Validator's existing 3-perspective `judge_root_cause`
(root_cause_trace.py) -- that produces planning|coder|skill_defect from
content-level judgment about WHY a bug happened; this produces core_engine
from a purely mechanical WHERE-did-the-change-land rule, independent of
whether anything went wrong. The two are orthogonal and only combined at
the call site (scheduler.py), never merged into one function.
Scope note: `frontend/` is deliberately excluded (05 §5.8 names the identity
files + engine source + schema, not the console UI -- a frontend/app.js bug
is much lower blast radius and doesn't need blue-green). `supervisor/` IS
included -- Deploy Supervisor modifying its own isolation/rollback logic is
at least as self-referentially risky as the engine it's protecting.
"""
import posixpath
_CORE_ENGINE_PREFIXES = ("src/", "supervisor/", ".claude/agents/")
def classify_core_engine_change(changed_files):
"""changed_files: iterable of repo-relative paths (posix-style, as
produced by `git diff --name-only` / `diff --git a/X b/Y` headers).
Returns True if ANY path falls under a core-engine prefix."""
for path in changed_files:
normalized = posixpath.normpath(path.replace("\\", "/"))
if normalized.startswith(_CORE_ENGINE_PREFIXES) or any(
normalized == prefix.rstrip("/") for prefix in _CORE_ENGINE_PREFIXES
):
return True
return False
def parse_changed_files_from_diff(diff_text):
"""Extracts repo-relative changed file paths from unified `git diff`
output (`diff --git a/X b/Y` header lines) -- avoids requiring a second
git subprocess call when the diff text is already on hand (e.g. as the
code_diff artifact's content)."""
changed = []
for line in (diff_text or "").splitlines():
if line.startswith("diff --git a/"):
rest = line[len("diff --git a/"):]
# "<a-path> b/<b-path>" -- split on the last " b/" occurrence
# since a path itself could theoretically contain " b/".
marker = rest.rfind(" b/")
if marker != -1:
changed.append(rest[:marker])
return changed