Skip to content

fix(canary): render repository-relative plan paths in canonical form - #6464

Merged
huangruiteng merged 1 commit into
loopx-project:mainfrom
JasonBuildAI:codex/agent-h5r9-windows
Oct 15, 2026
Merged

huangruiteng merged 1 commit into
loopx-project:mainfrom
JasonBuildAI:codex/agent-h5r9-windows

Conversation

@JasonBuildAI

@JasonBuildAI JasonBuildAI commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Impact: on native Windows the risk-based premerge gate this repository requires before self-merging (loopx canary premerge --from-git-diff, AGENTS.md) fails the gate's own contract smokes for every diff, because the canary plan renders repository-relative script paths with the host separator while the catalog, the suite checks, the shipped smokes and the docs all declare the canonical python3 examples/<...>.py spelling. A contributor or maintainer validating from a Windows checkout cannot obtain a trustworthy gate result until they hand-diff their failure set against a clean baseline, and the validation evidence recorded for the same diff (normalized.script, normalized.display_argv, selected_commands) differs between a Windows and a Linux run. Closes #6450.

Goal And Delivered Outcome

  • Outcome basis / optional anchor: issue [Bug]: native Windows canary premerge/smoke-suite renders repository-relative script paths with the host separator and fails the gate's own contract smokes #6450 (public bug report with a minimal reproduction at f713e0f07).
  • Goal/source and gap: loopx/canary/runner.py, loopx/canary/premerge.py and loopx/canary/planner.py rendered repository-relative plan paths with str(path.relative_to(repo_root)), so on a Windows host the plan payload carried examples\canary\... while its own command field, the catalog, the suite checks, docs/ and the shipped contract smokes declare examples/canary/.... Four shipping smokes reject that rendering; on POSIX hosts the two spellings are identical, which is why the defect survived.
  • Observable before → after, with the validation row that proves it: with the three renderers at the base revision the gate records 7 failures and 18/18 host-spelled selected_commands; with this head the same command records 5 failures and 0/18, and the risk-profile run drops from 3 failures to 1 (the remaining one is the pre-existing case below). Three of the four canary smokes return rc=1 before and rc=0 after. See the regression_parity and integration rows.
  • Issue/task and intended base: Closes #6450, intended base main at f43732cd7.

Author Declaration

  • Written by: GPT-5-based Codex agent (OpenAI), drafted at the request of and under the direction and review of the repository account owner.

Implemented against

Criterion (spec clause) Disposition Symbol / path Test or command
Repository-relative plan paths use the canonical POSIX spelling on every host implemented loopx/canary/runner.py, loopx/canary/premerge.py, loopx/canary/planner.py tests/canary/test_repository_root.py::test_plan_renders_repository_paths_in_canonical_posix_form
The shipped canary contract smokes stop failing on the rendering implemented examples/canary/smoke-suite-subdir-discovery-smoke.py, examples/canary/smoke-suite-runner-smoke.py, examples/canary/catalog-run-e2e-smoke.py direct runs, before → after
examples/canary/premerge-validation-gate-smoke.py passes on native Windows not_met (different host defect, tracked separately) examples/canary/premerge-validation-gate-smoke.py still fails while copying the POSIX scripts/loopx shim and executing it (OSError: [WinError 193]); unrelated to path rendering and failing identically before and after
The Windows lane keeps the rendering regression out implemented .github/workflows/python-tests.yml (windows-powershell job) new "Qualify the canary plan's repository path rendering" step
  • Self-check before submission: ran the four smokes, the new guard, and the premerge gate from a source checkout on this host before and after the change; read the diff for stray cleanup (none); deliberately left out the unrelated host defects listed under Coverage and gaps.

Scope And Continuation

Validation

  • Tested revision: 1cd935dd6f7748f52f5f4f9f60688393d005ca82 (rebased onto main 3c681f113; the gate before/after measurements below were taken on the identical tree d9f2fbb10 immediately before the rebase, and the focused checks — ruff, the guard test and the three smokes — were re-run green on 1cd935dd6)
  • Run state: finished
  • Input classes: public_fixture (the checks use the repository's own public catalog and smokes; no private or authorized data)
Check kind Result Public-safe evidence / limitation
static passed ruff check loopx/canary tests/canary → All checks passed!
unit passed pytest -q tests/canary/test_repository_root.py → 10 passed; 1 pre-existing failure (test_example_symlink_cannot_escape_selected_checkout, needs Windows symlink privilege, fails at base too)
regression_parity passed the new guard against the unfixed product files → 1 failed (AssertionError: examples\canary\catalog-root-smoke.py); against this head → 1 passed
integration passed smokes smoke-suite-subdir-discovery, smoke-suite-runner, catalog-run-e2e: rc=1 before → rc=0 after; canary premerge --changed-file loopx/quota.py --profile canary-runner on the same host: 18 selected, 7 failures, 18/18 host-spelled commands before → 18 selected, 5 failures, 0/18 after; risk-profile run 3 → 1 failures
integration failed examples/canary/premerge-validation-gate-smoke.py: AssertionError before (rendering), OSError: [WinError 193] after executing the copied POSIX scripts/loopx shim — a separate pre-existing host defect, unchanged by this PR
real_entrypoint passed canary premerge --changed-file loopx/canary/runner.py --profile canary-runner --no-progress --format json on this head: every recorded plan command renders POSIX-only; risk profile selects 8 checks with 1 failure (the pre-existing case above)
static failed mypy reports loopx/control_plane/effect_runtime.py:437: Module has no attribute "WNOHANG" — pre-existing on this host, documented by #6368; not touched here
  • Coverage and gaps: the changed paths are exactly the three renderers, the guard and the CI step. The other checks failing on this host during the same gate run (examples/control_plane/hot-path-interface-budget-smoke.py, cli-output-budget-regression-smoke.py, quota-plan-smoke.py, monitor-scheduler-contract-smoke.py) fail identically before and after and are outside this change.

Frontend / Visual Evidence

  • UI impact: none
  • Before: N/A
  • After: N/A
  • States and viewports shown: N/A
  • Source data: none
  • Attention review: N/A — no user-visible surface changes
  • Craft review: N/A

Type of Change

  • Bug fix

LoopX Area

  • Build, packaging, installer, or CI

Technical Direction

  • Direction / acceptance reference, when applicable: N/A — bounded host-portability repair of an existing public gate contract.

Shared-authority RFC fixture impact

  • Production-scale fixture schema: N/A
  • Semantic dimensions changed, or reviewed no-impact rationale: N/A — no typed vocabulary, state classification or protocol literal is introduced.
  • Provider conformance arms run: N/A
  • Read-only legacy/file/PostgreSQL three-arm rehearsal (required for promotion, runtime-routing, or compatibility-projection changes): N/A

Boundary Checklist

  • Neither the diff nor this PR body/comments/attachments disclose private state, credentials, raw traces or verifier output, internal links, or local machine paths.
  • I did not duplicate maintainer-owned benchmark work unless a maintainer split out a public issue for it.
  • I kept the change scoped to the linked issue/task.
  • I completed the visual evidence section for UI changes, or marked UI impact none.
  • Every commit includes a DCO Signed-off-by trailer (git commit -s).

JasonBuildAI added a commit to JasonBuildAI/loopx that referenced this pull request Oct 14, 2026
…#6464 and collision note PR loopx-project#6452

Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
The canary plan and the premerge evidence rendered repository-relative
script paths with the host separator, so on native Windows
`normalized.script` and `normalized.display_argv` disagreed with the
check's own declared `python3 examples/<...>.py` command identity. The
gate's shipped contract smokes (catalog-run-e2e, premerge-validation-gate,
smoke-suite-runner) and smoke-suite-subdir-discovery rejected every diff, so
`loopx canary premerge --from-git-diff`, the risk-based validation set
AGENTS.md requires, could not go green on Windows.

Render the normalized `script` field, the `_display_argv` path entries, the
public-boundary `--scan-path` value and the catalog `_display_path` with
`.as_posix()`, matching the renderers already used elsewhere in the same
package, and extend tests/canary/test_repository_root.py with a guard that
rejects a host separator in a plan's repository paths. The native Windows CI
job runs that guard so the regression cannot come back.

Fixes loopx-project#6450

AI disclosure: this change was drafted with AI assistance at my request,
under my direction and review.

Signed-off-by: JasonBuildAI <jasonbuildai@gmail.com>
@JasonBuildAI
JasonBuildAI force-pushed the codex/agent-h5r9-windows branch from d9f2fbb to 1cd935d Compare October 14, 2026 20:56

@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; reasoning_effort=xhigh; declaration_source=runtime_reported

动机

评审 1cd935dd6f7748f52f5f4f9f60688393d005ca82(base 3c681f1132fe719e01f75e5a41bfd854dfa9e346)。从不同操作系统验证改动的贡献者,需要让同一个检查在计划、报告与后续消费中有一致的名称。旧输出把宿主分隔符混入仓库相对路径,检查自身就可能因名称不一致报错,贡献者需要反复区分这种基础问题与实际改动失败。同一仓库脚本在 Windows 风格下原先被记录成反斜线形式,与目录声明不一致;现在五处都输出规范斜线形式,实际执行参数和仓库范围检查保持。受控对照中五处字段从全部不匹配变为全部符合既有目录约定,真实本地 canary 入口和范围拒绝继续通过。本次批准限定为路径表示修复;不证明原生 Windows 五条入口全绿,也不关闭宿主 shim、权限或其他历史资格缺口。原生 Windows 的完整五命令资格仍未独立验证;作者记录的 POSIX shim 执行问题继续属于原 #6450 的剩余入口缺口。

改动思路

路径展示归 runner、premerge、planner 各自的输出边界;选择 checkout、执行绝对 argv 和写保护仍由既有 owner 决定。本次仅修正五处仓库相对路径表示并接入既有 Windows 测试 lane,不改变实际执行命令或修复其他宿主问题。 仓库目录和其他 canary renderer 已采用 POSIX spelling,这里将既有 str(relative) 改为 relative.as_posix();失败与越界处理没有搬到新 helper。展示 argv 仍先复制原列表。对仓库外路径保留原 fallback,没有把展示规范误用为新的文件执行授权。

具体改动

关键代码讲解

  1. normalize_canary_command(runner.py:92)让 normalized.script 使用规范相对形式;同文件 _display_argv:159 处理绝对且位于当前 checkout 的显示 token。实际 argv 仍携带原解释器、绝对脚本与参数。
  2. premerge._display_argv(premerge.py:341)规范化其可解析的仓库内 token;_public_boundary_changed_files_run:156 规范化 --scan-path 的记录表示,文件存在性、实际扫描路径和策略不变。
  3. planner._display_path(planner.py:1388)对仓库内 catalog source 输出相对 POSIX spelling,仓库外仍回退原字符串。共五处运行时转换。
  4. test_repository_root.py 新增完整计划 guard,先显式拒绝反斜线,再检查 canonical form,避免测试先归一化而掩盖缺陷;现有 windows-powershell job 在已安装 Python test dependencies 后运行这一个 guard。没有新增 job、调度或 CI 权限。

完整五路径 +62/-5、一份 DCO。对照 #6450 的 canonical_repository_path_identity 与 windows_guard_wiring:代码与测试接线 implemented,CI 接线仅审阅源码,没有执行或读取 CI。whole_native_windows_five_commands deferred;原 issue 的五命令全绿不能由本次局部批准代替,宿主 shim 与完整 Windows 出口仍须原 owner 继续验收。

对主干的风险

主要风险是误改实际执行路径、范围检查,或把跨平台显示修复描述成完整 Windows gate 修复。本轮在相同 base/head 独立运行整个 canary 单测:47 →48 passed,均 0 skipped。同一私有探针调用五处真实产品函数,以 POSIX IO 配合明确标注的 Windows 拼写 adapter:基线五字段均输出不匹配的反斜线,head 五字段全部符合目录的斜线约定;同时检查 stdlib PureWindowsPath、原 argv 不被修改,以及两侧越界/shell 输入均拒绝。这是表示层反例,不是原生 Windows 运行。

当前实际 Mac canary premerge --from-git-diff 为 5 direct +15 selected,零失败/hold,包含四个公开 canary smokes 与变更文件公开边界扫描。Ruff、正常 imports 的三文件 mypy、diff/compile、DCO、先 advisory 后全量 semantic 通过。本地 POSIX 能通过这些命令,不证明 Windows 也通过;作者记录的 WinError 193、symlink 权限、WNOHANG 以及其他全 gate 失败未在本轮独立重验,也没有被删除或改成 pass。未查询、等待或 dispatch hosted CI。

语义与 CI 对齐

复用既有路径身份约定,未新增协议状态或词汇。advisory 三源码未发现支持的 vocabulary carrier,仍人工追踪五个动态字符串出口;全 27 vocabulary 检查通过。Windows 的记录字符串默认改变已披露,旧历史不重写。测试 lane 会运行新 guard 是源码接线事实,不是已获得 Windows 执行资格的证据。

我的整体评价

APPROVE,justified_increment,限定于仓库相对路径表示。 long_horizon improved:相同检查的记录身份更一致;user_experience preserved:实际本地入口、执行参数与拒绝边界保留,原生 Windows 整体体验仍未验收。已做有界前向重构检查:三处 formatter 对绝对/可解析 token 与仓库外 fallback 的职责不同,未为五个纯格式转换新增带参数的通用层。修复可独立回滚,机制与已复现问题相称;本批准不关闭原 issue 的剩余 Windows 退出条件,也不授予合并、CI 或安装权限。

English verdict: APPROVE — 1cd935dd6f7748f52f5f4f9f60688393d005ca82 canonicalizes five repository-relative plan/evidence renderers while retaining execution argv and confinement. Independent five-field Windows-spelling counterfactuals, 48 Mac canary tests and the local risk gate pass. Native Windows and the full five-command acceptance remain unqualified.

@huangruiteng
huangruiteng merged commit a82e132 into loopx-project:main Oct 15, 2026
41 of 55 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

3 participants