Skip to content

fix(launcher): recover from broken equal-minor PATH shadows - #7798

Merged
huangruiteng merged 1 commit into
mainfrom
codex/python-path-shadow-recovery-20261101
Nov 1, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/python-path-shadow-recovery-20261101

Conversation

@BigDataDZ

Copy link
Copy Markdown
Contributor

Goal And Delivered Outcome

  • Outcome basis / optional anchor: reproduced interpreter discovery failure in the existing source launcher.
  • Goal/source and gap: discovery enumerates minor-version names but resolves each through command -v only once. A broken first python3.x hides a working python3.x later on PATH, causing an older alias to win or startup to fail despite a usable interpreter.
  • Observable before → after: four native subprocess cases report 3 passed / 1 failed on unchanged main and 4 passed after the repair. The failed case selects the older alias instead of the working later equal-minor executable.
  • Issue/task and intended base: self-contained repair on main at ec91c4dbbb9aecf0abd0395455fc52466506f2b2.

Author Declaration

  • Written by: model_agent — OpenAI Codex, under the contributor's direction.

Implemented against

  • Specification and revision: existing version validation and numeric discovery order in scripts/loopx-python.sh, plus test_equal_minor_preserves_path_precedence in tests/test_python_discovery.py, at the base above. This PR's request supplies recovery from a nonfunctional shadow.
Criterion Disposition Symbol / path Test or command
Try a working equal-minor interpreter behind a broken PATH entry implemented select_loopx_python versioned discovery loop python_path_discovery.test.ts
Preserve numeric minor priority and equal-minor PATH order implemented existing versioned_python_names, unchanged same four-case suite
Reject a broken higher minor and execute a working lower candidate implemented existing version probe and --exec suite runs real Python through tagged wrappers
  • Self-check before submission: reviewed discovery and caller precedence. Iterate the original PATH directories for each already-sorted name rather than losing those candidate paths through a single command -v. No new version policy, external utility dependency, option or protocol is introduced.

Scope And Continuation

  • Completed scope and remaining work: complete within PATH candidate recovery. Explicit and recorded configuration, project-environment precedence and user-install fallback retain their existing branches.
  • Slice boundary / successor: N/A. This is independent of fix(launcher): accept CRLF Python runtime records #7796's record line-ending fix: both target main, touch separate owning branches and need neither commit to function.
  • Bounded refactoring pass: retain the existing name enumeration and version probe; a small nested directory scan avoids introducing a second sorting/serialization contract.

Validation

  • Tested revision: the commit on this PR.
  • Run state: finished
  • Input classes: synthetic
Check kind Result Public-safe evidence / limitation
regression_parity passed Same four cases: base 3 passed / 1 failed; repaired source 4 passed. The failing-before case exercises broken-first / working-later equal minors.
real_entrypoint passed Windows Git Bash plus Python 3.12: actual shell selector and --exec execute a real interpreter. Temporary PATH entries include spaces; filename minor numbers are synthetic discovery inputs, not claims of installed Python versions.
unit passed New suite plus existing test_python_runtime.test.ts: 7 passed; 2 existing POSIX-only cases skipped.
static passed Strict targeted TypeScript compile, bash -n, diff whitespace check, RFC bilingual check. Advisory found no supported changed product vocabulary; test matrices remain local inputs.
integration not_run Native Linux/macOS and full repository suite unavailable in this validation run; hosted checks are still required.
  • Coverage and gaps: tests distinguish recovery, healthy equal-minor ordering, higher-minor preference and broken-higher fallback. This is real subprocess handoff coverage, not packaged App/frontend validation. No model or benchmark execution, active Goal writes, or system changes.

Frontend / Visual Evidence

  • UI impact: none; existing source-launcher recovery only. No caller-facing capability or frontend/Lark operation is added.

Type of Change

  • Bug fix
  • Test update

LoopX Area

  • Build, packaging, installer, or CI

Technical Direction

  • Direction / acceptance reference: nearest existing bootstrap interpreter owner; no capability/provider addition or parallel control-plane authority.

Shared-authority RFC fixture impact

N/A: no authority schema, provider routing or projection changes.

Boundary Checklist

  • No private state, credentials, raw evidence, internal links or machine paths in public artifacts.
  • No maintainer-owned benchmark work duplicated.
  • Single interpreter recovery defect with focused validation.
  • No paired RFC changed; bilingual check passed.
  • UI impact is none.
  • Every commit includes DCO sign-off.

Signed-off-by: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max

动机 / Motivation

通过源码启动 LoopX、且 PATH 中存在多个同名 Python 的用户。前面的同 minor Python 失效时,即使后面有可用的同名程序,旧选择器也会退到较旧别名或启动失败;当前会继续按原 PATH 顺序验证候选,执行后面的可用解释器。已验证真实 Bash/Python 执行、结果文件值 42 和完整参数回读;显式配置、记录、venv 的优先级以及失败后修正重试均保留。范围是现有 PATH 发现分支的恢复;不增加版本策略、配置或权限,也不把合成的 minor 名称当成真实安装版本。

改动思路 / Approach

已有选择器负责配置优先级、数字 minor 排序和实际版本探测,直接在它内部补齐同名候选遍历即可。本 PR 只在现有排序后的名称内依次验证 PATH 目录,不增加解析器、状态、外部工具或新的启动入口。原来的 command -v 每个名称只返回一次结果,因而无法表达“同名的第一个坏了,继续检查下一个”。补丁沿用已有名称排序和版本探测,仅把每个名称对应的候选路径逐个交给原来的验证函数。可用的早期同 minor 仍优先,坏的高 minor 仍能回退到可用的低 minor。

主启动器和 Dashboard 继续使用同一个 companion selector;缺少 helper 的旧发布快照回退、JS 构建器的平台适配保持原边界。源启动的一次请求不增加配置、确认或手工复制信息;只有显式配置确实无效时才要求修正,然后沿同一入口重试。

具体改动 / Changes

完整差异为 2 个文件,+63/-5;生产脚本 +8/-5,新 TypeScript 回归文件 +55。评审 head 4b1ddc7af39118345ab3632b959165e25ae8832c,不可变 merge base ec91c4dbbb9aecf0abd0395455fc52466506f2b2。

没有找到单独针对“坏的同 minor PATH 影子”的成文规格。已先读取该基线的共享选择器、test_equal_minor_preserves_path_precedence,以及既有开发指南:以 Python 3.11+、已有配置顺序和可复现恢复缺陷为判断依据,新增测试本身不充当规格。

关键代码讲解

  1. versioned_python_names 未改动,仍按数字 minor 排序、去重名称,并排除非数字后缀。它定义候选名称的优先级,不判断某个程序是否真正可用。

  2. select_loopx_python 在已有排序后的名称内遍历原 PATH 目录,使用完整候选路径调用既有版本探测。空 PATH 项仍表示当前目录,空格和相对目录不因拆分而丢失;显式配置、安装记录和项目 venv 在这段之前继续拥有原优先级。

  3. --exec 入口 保留原参数转交和失败退出。独立验证让不同候选执行同一个真实 Python,但写入不同选择标识,并回读值为 42 的文件与带空格参数,因此不会把“较旧别名碰巧也退出成功”误算为修复。另行通过实际 scripts/loopx --version 验证主调用入口可用。

检查 结果
新 PATH 测试与既有运行时测试 9 PASS,0 SKIP
既有 Python 发现模块 7 PASS
独立同输入 base/head 当前 16/16 PASS;3 个影子恢复场景在基线选错别名,当前选择正确;其余控制保留
范围与恢复 PATH 外的邻居不参与;新增候选下次可用;无效显式配置不能借记录绕过;修正后真实执行并回读结果
Bash、严格 TypeScript、语义、公开边界 PASS
标准 premerge 4 项直接检查和 9 项目录检查 PASS;1 项既有维护性 advisory 仍 FAIL

对主干的风险 / Risks

未发现阻塞问题。最强反例是错误地选择了另一个仍可执行的解释器,所以独立检查比较实际选择标识、文件结果和参数,而非仅看退出码。还覆盖显式/记录/venv 优先级、另一个 CWD 的记录、PATH 外候选、后续新增候选、相对目录和空 PATH 项。共享 helper 的生产调用路径已在不可变 base/head 核对,未新增无消费者的模块。

主干已另含 #7796 的记录行尾修复及 Dashboard 的 Node 准入更新;本 PR 的改动位于后面的 PATH 发现分支,未把这些主干变化冒领为本 head 的验证结果。旧 helper-absent 发布快照和 JS 平台适配仍是独立兼容边界。本轮平台为 macOS/Bash/Python 3.12.15,未独立运行原生 Windows 或安装后的 App;minor 文件名是合成输入,未声称实际安装 Python 3.98。

run_host_process 的维护性 ratchet 保持 FAIL。独立基线/当前同命令执行的完整失败 SHA256 均为 9d88719f4a1548b47726f28ad226ff76e2ef1844c616d83f2ce46170a14838fe;oracle、预算配置和报错模块字节相等,当前改动不在该失败因果路径。没有放宽预算,也不声称整个扫描树相同。当前所改两路径有通过的必需验证,CQR 为 pass。

语义与 CI 对齐

这是已有启动路径的默认恢复修复,没有 default-off 声明。实际版本检查与显式配置失败停止语义保留,数字名称次序继续复用原 owner。测试矩阵的 as const 是本地输入,没有新增 Goal 状态、权限或共享协议词汇。本轮没有查询、轮询或等待 CI;作者未运行的其他平台保留为未验证范围。

我的整体评价 / Verdict

goal_achieved 限于这个解释器发现缺陷。长程连续性为 preserved:无效配置仍停止,修正后的下一次执行达到实际结果,不增加状态同步或无限重试。用户体验为 improved:同一启动意图可以利用已经存在的可用解释器,普通路径零新增确认轮次;这不是测得了长期效果或费用收益。

已检查共享 Bash 选择器、主启动器和 Dashboard 调用路径;没有页面或布局改动,视觉评审不适用。本轮平台为 macOS/Bash/Python 3.12.15,未独立运行原生 Windows 或安装后的 App;minor 文件名是合成输入,未声称实际安装 Python 3.98。已有选择器负责配置优先级、数字 minor 排序和实际版本探测,直接在它内部补齐同名候选遍历即可。本 PR 只在现有排序后的名称内依次验证 PATH 目录,不增加解析器、状态、外部工具或新的启动入口。代码与问题规模相称,局部遍历是已完成的简化;未发现必须扩大框架或语言迁移的依据。评审通过仍与合并、安装和发布授权分开。

English verdict: APPROVE at 4b1ddc7af39118345ab3632b959165e25ae8832c. The PATH-shadow recovery is independently validated; platform and inherited maintenance limits remain disclosed.

@huangruiteng
huangruiteng merged commit b000bf3 into main Nov 1, 2026
26 of 35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants