Skip to content

fix(issue-fix): verify GitHub repository redirects in PR wait observation - #7988

Merged
huangruiteng merged 1 commit into
mainfrom
codex/pr-wait-repository-redirect-20261103
Nov 3, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/pr-wait-repository-redirect-20261103

Conversation

@cocolord

@cocolord cocolord commented Nov 3, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Fixes a false waiting_external block after a GitHub repository rename.

A recorded PR dependency keeps its number when the repository moves to a new owner, but the provider URL then names the canonical owner. The wait reconciler compared the recorded URL byte-for-byte, so a valid merged dependency was rejected as PR dependency provider identity mismatch and the Todo stayed blocked.

  • fetch_github_pr_lifecycle_payload now verifies the provider response against the requested repo/number and, when the owner differs, asks GitHub for the canonical name with gh repo view <repo> --json nameWithOwner.
  • validate_github_pr_provider_identity accepts the dependency only when the canonical name matches the provider URL repository. Malformed responses, unrelated same-number PRs and failed verification still fail closed.
  • The verified canonical repo is carried on a transient _loopx_verified_requested_repository payload field for the reconciler; it is not persisted into the lifecycle packet or rollout evidence.
  • Adds coverage for the rename path at both the fetch and native wait-turn levels (File and SQLite providers).

Validation

  • pytest tests/capabilities/test_issue_fix_pr_lifecycle_review_response.py tests/capabilities/test_pr_wait_observation.py — 57 passed.
  • Broader issue-fix / PR-wait set — 59 passed, 8 failed; all 8 reproduce identically on pristine origin/main ac74f90c4 (test_pr_wait_lifecycle.py cached-readiness and host-inheritance cases, and two SQLite grouped-monitor materialization cases).
  • python examples/issue-fix-pr-review-reconcile-smoke.py — ok.
  • Ruff on all changed Python files — passed.
  • loopx canary premerge --from-git-diff --git-diff-base origin/main — direct checks and changed-file compile passed. Two catalog canaries fail identically on pristine origin/main 6020ddf57 and are inherited, not caused by this diff: issue-fix-pr-lifecycle-smoke.py (KeyError: 'evidence' when reading the active-state projection) and semantic-vocabulary-drift-smoke.py (pre-existing budget slack).

Boundary

Touches the issue-fix PR wait observation behavior. No merge authority is claimed; maintainer review and merge are required.

CI status (run 41632739505 / 41632739409)

  • kernel-static-checks fails on F811 in tests/test_lark_private_conversations.py; the duplicate fixture request was introduced by fix(chat): retain native completion before response parsing #7986 on main and is unrelated to this diff. Fixed in fix(tests): mark injected Lark fixtures for lint #7991. This PR will be rebased onto the fixed main before merge.
  • Release Artifacts / build fails in examples/personal-workspace-browser/research-display-language.mjs with a 30s waitForFunction timeout. This diff only touches issue-fix PR-wait code; the same scenario passed on earlier Release Artifacts runs, so it will be rerun after the rebase.
  • checks, pytest, and merge-gate failures are downstream of kernel-static-checks.

…tion

A renamed GitHub repository keeps its pull request numbers, but the provider
URL now names the canonical owner. Comparing the recorded dependency URL
byte-for-byte therefore rejects a valid merged dependency and leaves the
Todo blocked on a PR that already landed.

Verify the redirect with `gh repo view <repo> --json nameWithOwner` and
accept the dependency only when the canonical name matches the provider
URL repository. Malformed responses, unrelated same-number PRs and failed
verification still fail closed; the verified canonical repo is carried on
the transient payload for the wait reconciler and is not persisted.

Signed-off-by: lusendong.6789 <lusendong.6789@bytedance.com>
Co-authored-by: TRAE CLI <traecli@bytedance.com>
@cocolord
cocolord force-pushed the codex/pr-wait-repository-redirect-20261103 branch from 583c5db to 96f55db Compare November 3, 2026 12:05

@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; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max

动机 / Motivation

使用 issue-fix 自动等待 GitHub PR 合并的用户,在仓库更名后仍可能持有原仓库地址。 原来 GitHub 已返回同一个 PR 的规范新地址,等待器仍按旧地址逐字比较而拒绝,导致合并后的工作无法继续;现在先核验仓库重定向,再允许相同 PR 编号的已验证别名。 已验证的结果是 File 和 SQLite 上,真实等待、合并事实记录和后续任务可以从更名后的依赖继续,重放不会重复执行或结算。 本 PR 只修复 PR 身份观察,不新增合并权限,不自动关闭用户目标,不把任意同编号 PR 当成同一个依赖。 生命周期目录 smoke 和六个既有等待测试仍失败,严格质量回执不通过;真实应用 Host 与跨平台行为没有完成资格验证。

改动思路 / Approach

先比较 PR 类型和编号;仓库相同时维持原路径,仓库不同时才调用 gh repo view 取请求仓库的规范名称,要求它与 provider 返回的仓库一致。核验结果只在当前 provider 数据中传递,不写一个需要人工同步的别名表。身份不变量由 issue-fix 的既有 GitHub provider 校验,规范仓库名由 provider IO 获取,合并事实与后续执行仍交给原有 owner;没有为别名再建一份持久状态。 当前交付边界是更名依赖的身份核验与既有等待恢复,不扩展合并、调度或结算权限。

输入情况 当前结果
同仓库、同编号且 MERGED 沿原路径记录合并事实
已核验重命名、同编号且 MERGED 接受别名,进入原继续执行路径
无关仓库、错误编号、缺失 URL、查询失败 拒绝身份,不生成合并事实
身份正确但 OPEN/CLOSED 保持未合并语义

表格是精确 head 的源码分支说明;执行证据另列在风险部分。

具体改动 / Changes

规范依据:docs/reference/todo-continuation-readback.md,固定版本 6020ddf57e4975dd08a9b02101fd51b2ecda48e8;并核对同版本 loopx/capabilities/issue_fix/README.md 的身份及等待约定。规范原文没有编号,下列是定位名称而非新增政策:same-pr repository-alias identity 已实现同编号与规范仓库双重核验;existing pr_merge observation and continuation 已实现沿原事实写入与继续执行 owner 运行,未把观察变成执行授权。

关键代码讲解

4 个文件、+129/-4,把新增成本限制在 provider IO、一个身份判断和对应测试。普通路径不多查仓库,重命名路径多一次只读查询;没有新 CLI、持久配置、通用核心状态或第二个继续执行实现。

对主干的风险 / Risks

最大反例是误认无关仓库的同编号 PR,让尚未满足的依赖继续。PASS:File/SQLite 的20个生产 fetch→native 用例覆盖正确别名、无关仓库、错误编号、缺 URL、查询失败、坏 JSON、超时、OPEN/CLOSED;只有正确身份的合并响应产生事实,后创建的无关同编号依赖仍不就绪。真实 GitHub 对旧仓库 #7102 的只读响应已确认规范地址及编号;未获取或等待 CI。

PASS:相同原生继续执行 fixture 在 head 的两个后端都达到一次协议 Host、一次合并事实、一次结算和独立产物验收,重放没有额外 GH/Host/副作用;base 因旧 URL 比较被阻塞且零副作用。协议 Host 是合成实现,只有 GitHub JSON IO 被替换,不声称验证真实 App 或付费模型。Ruff、语义检查和 premerge 的6项直接检查通过。FAIL:扩展测试 head68通过/6失败、base65通过/6失败,六项均在改动前的观察 fixture 返回 None 后报同样 TypeError;原生 catalog 的生命周期 smoke 在 base/head 同样于571行报 KeyError: 'evidence'。最终9项选中检查8通过、1失败,既有维护性预算建议也保留。严格 CQR 失败,quality_invalid_receipt 合并限制没有取消。

我的整体评价 / Verdict

没有发现当前 PR 引入的阻塞问题,APPROVE。长期工作路径判定 improved,仅限已验证的依赖恢复与一次结算/重放;用户体验判定 improved,已有原地址无需人工改写或新增确认即可继续,失败仍走原恢复路径。身份不变量由 issue-fix 的既有 GitHub provider 校验,规范仓库名由 provider IO 获取,合并事实与后续执行仍交给原有 owner;没有为别名再建一份持久状态。 当前交付边界是更名依赖的身份核验与既有等待恢复,不扩展合并、调度或结算权限。 接受输入的变化明确且符合已有别名约定,不改变默认开关、权限或 quota。复用既有身份词汇,内部证明字段只是当前 provider 数据的派生投影。检查过的 issue-fix provider 与等待入口没有渲染内容改动,视觉评审不适用;真实应用 Host、Windows 和整套既有测试失败仍未解决。评审结论与 CQR、集成验证、合并授权分别保留,不能据此宣称可直接合并。

English verdict: APPROVE at 96f55db339ec335f915ccf71f611cfb90cba8717. Verified repository redirects restore the existing continuation path without accepting foreign PRs; strict quality and lifecycle-smoke holds remain.

@huangruiteng
huangruiteng merged commit 29360c8 into main Nov 3, 2026
23 of 29 checks passed
@huangruiteng
huangruiteng deleted the codex/pr-wait-repository-redirect-20261103 branch November 3, 2026 14:39
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