@@ -331,22 +331,69 @@ negative 或 mutation-style 断言,并让各 provider 复用同一 envelope
331331经 review 的兼容理由,不得削弱或删除已有维度。禁止复制生产文本、标识、路径、日志、
332332凭据或私有快照。PR 验证证据需报告 fixture schema、语义维度、provider arms 与有意差异。
333333
334- Install the test dependencies once:
334+ ### Local Validation Environment / 本地验证环境
335+
336+ Run from the repository or dedicated worktree root with ` uv ` . The project's
337+ ` requires-python ` declares Python ` >=3.11 ` ; it does not require an executable
338+ named ` python3.11 ` . ` uv ` selects a compatible interpreter, creates ` .venv ` , and
339+ installs the checkout with the selected extras. Interpreter downloads depend on
340+ uv's download settings and network access. A system ` python3 ` may be too old,
341+ and a global ` loopx ` may resolve to a different installed source tree.
342+
343+ 在仓库或独立 worktree 根目录使用 ` uv ` 。` pyproject.toml ` 要求 Python ` >=3.11 ` ,
344+ 无需依赖名为 ` python3.11 ` 的命令。uv 选择兼容解释器,在 ` .venv ` 中安装当前源码
345+ 与测试依赖;能否自动下载 Python 取决于下载配置与网络。系统 ` python3 ` 可能过旧,
346+ 全局 ` loopx ` 也可能指向另一个已安装版本。
335347
336348``` bash
337- python -m pip install -e " .[test]"
349+ uv sync --extra test
350+ uv run --extra test python -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation
351+ uv run --extra test python -m mypy
352+ uv run --extra test python examples/control_plane/cli-output-budget-regression-smoke.py
353+ uv run --extra test python -m pytest -q
354+ uv run --extra test loopx canary premerge --from-git-diff
355+ # For a fork whose PR base is upstream/main, use this instead:
356+ uv run --extra test loopx canary premerge --from-git-diff --git-diff-base upstream/main
357+ # Run one semantic smoke or check its generated inventory:
358+ uv run --extra test loopx canary smoke-suite --script semantic-vocabulary-drift-smoke.py
359+ uv run python scripts/generate_semantic_inventory.py --check
360+ git diff --check
338361```
339362
340- Run the fast repository gate :
363+ Confirm the interpreter and imported checkout when diagnosing a mismatch :
341364
342365``` bash
343- python -m ruff check tests loopx/canary loopx/control_plane loopx/domain_packs loopx/presentation
344- python -m mypy
345- python examples/control_plane/cli-output-budget-regression-smoke.py
346- python -m pytest -q
347- git diff --check
366+ uv run python -c " import sys, loopx; print(sys.executable); print(loopx.__file__)"
348367```
349368
369+ Canary executes Python checks with the interpreter that launched LoopX
370+ (` sys.executable ` ). Its displayed ` python3 ` command is not a second interpreter
371+ selection. Keep subprocesses on ` sys.executable ` ; use ` uv run ` at the developer
372+ entrypoint. Avoid ` uvx loopx ` or ` uv run --no-project ` when validating this
373+ checkout, and change into the intended worktree before running Git-based checks.
374+ An activated compatible environment remains a supported alternative: install
375+ with ` python -m pip install -e ".[test]" ` , then use that environment's Python
376+ and LoopX commands directly.
377+
378+ Canary 使用启动 LoopX 的 ` sys.executable ` 执行 Python 检查,显示的 ` python3 `
379+ 不是重新选择解释器。子进程继续复用 ` sys.executable ` ,只在开发入口使用 ` uv run ` 。
380+ 检查当前源码时不要改用 ` uvx loopx ` 或 ` uv run --no-project ` ;Git diff 检查前先进入
381+ 目标 worktree。已有兼容虚拟环境也可用 ` python -m pip install -e ".[test]" ` 安装源码,
382+ 随后直接使用该环境的命令。
383+
384+ The repository does not currently track ` .python-version ` or ` uv.lock ` . ` uv `
385+ creates a local lockfile during resolution; keep that generated file out of
386+ unrelated PRs. Introducing a shared lock or interpreter pin is a separate
387+ repository policy change. Do not claim identical environments from
388+ ` requires-python ` alone, or use ` --locked ` before a reviewed lockfile exists.
389+ CI keeps its explicit Python versions and pinned/hash-checked installation
390+ paths. Historical validation receipts keep the commands that actually ran.
391+
392+ 当前仓库未跟踪 ` .python-version ` 或 ` uv.lock ` 。uv 解析依赖时生成的本地锁文件不要
393+ 混入无关 PR;共享锁文件与解释器版本固定应单独评审。最低版本要求不等于环境完全
394+ 可复现,没有已评审锁文件时也不使用 ` --locked ` 。CI 保留显式 Python 版本与固定依赖/
395+ 哈希校验的安装路径,历史验证记录保留实际执行过的命令。
396+
350397` .github/workflows/python-tests.yml ` runs this fast lane for relevant Python
351398pull requests. It intentionally excludes provider-backed evaluation and the
352399full smoke catalog, so ordinary iteration does not depend on credentials,
@@ -377,7 +424,7 @@ Sonar 只复用同一次 run 的 XML,不重复测试、不跨 run 取产物。
377424Sonar,测试 job 不接收 Sonar secret。触发范围取原有两套 workflow 的并集;纯前端
378425PR 使用前述豁免,Sonar 配置变更仍全量运行,包括没有 token 的 fork。
379426
380- Reproduce one shard locally with `python -m pytest -q -n 2 --splits 4 --group 1
427+ Reproduce one shard locally with `uv run --extra test python -m pytest -q -n 2 --splits 4 --group 1
381428--splitting-algorithm least_duration --cov=loopx`. Omit the split arguments to
382429run the complete suite locally. 全量本地测试仍省略分片参数即可。
383430
0 commit comments