feat: 3.2.17中途变更处理(git驱动) + 3.2.9a Worker git强制 + 3.2.5 Phase7 squash merge + Arc git初始化检测

- 新增 ChangeClassifier(爆炸半径分类:IMPLEMENTATION/INTERFACE/GLOBAL_CONSTRAINT)
- 新增 ImpactPropagator(BFS影响传播:IMPACTED/BOUNDARY/SAFE差异化标记)
- task_graph.py:invalidate_by_adr()差异化失效 + CascadeReport扩展字段(向后兼容)
- eng_mode.py:三阶段差异化流程(分类→传播→失效→git操作→验证任务→重规划)
- eng_mode.py:_git_squash_merge_and_tag() + Phase 7 集成
- do_mode.py:_ensure_all_committed() Worker git操作强制
- adr_watcher.py:内容快照 + get_content_for_classification()
- events.py:ADR_CLASSIFIED/IMPACT_PROPAGATED/BOUNDARY_VERIFICATION_GENERATED
- partial_replanner.py:replan_with_constraints() + generate_verification_tasks()
- project_bootstrap.py:ensure_git_initialized() Arc规划前检测
- test_p1_21_phase2.py:21个新测试,95个全量测试0失败

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
AirPlan
2026-06-15 14:45:41 +08:00
parent a60d1a0c04
commit 9702f1b186
11 changed files with 1351 additions and 82 deletions

View File

@@ -17,6 +17,30 @@ from air_runtime.contracts import WorkerResult, now_iso
from air_runtime.utils import sanitize_task_id, session_stamp
def _ensure_all_committed(project_root: Path, task_id: str) -> None:
"""3.2.9a: Worker git 操作强制 — 检查所有变更已提交。
在 Worker finish 前强制检查 git status未提交的变更阻止完成。
确保 Worktree 分支上所有修改都已 git add + git commit。
"""
import subprocess
try:
r = subprocess.run(
["git", "status", "--porcelain"],
cwd=project_root, capture_output=True, text=True, timeout=10,
)
if r.returncode != 0:
return # git not available, skip check
if r.stdout.strip():
raise RuntimeError(
f"Worker {task_id}: 存在未提交的变更,禁止 finish。\n"
f"未提交文件:\n{r.stdout.strip()}\n"
f"请先 git add && git commit 后再 finish。"
)
except FileNotFoundError:
pass # git not available, skip check
# GUI 任务检测关键词
GUI_INDICATORS = {
"gui", "ui", "render", "layout", "dialog", "osd",
@@ -204,6 +228,9 @@ def finish_worker(project_root: Path, task_id: str, result_path: Path | None = N
tid = sanitize_task_id(task_id)
paths = _paths(project_root, tid)
# 3.2.9a: Worker git 操作强制 — 所有变更必须已提交
_ensure_all_committed(project_root, tid)
# 加载 result
if result_path and result_path.exists():
result_data = safe_json_load(result_path)