fix(release): repair registry, installer and usage qualification failures - #5151
Conversation
a034819 to
018b9b6
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
English verdict: APPROVE. No blocking finding at b2ae4f323df0f3e760b57cd7f764e6a41a61f60d against 0b715579def6bb4c4921f429aa71df4e54c1e466. Runtime/installer merging remains a separate maintainer gate; this review does not grant that authority. GitHub CI was not consulted under repository policy.
动机
1.2.1 的真实发布验证重现了两个故障:global registry 的锁文件无写权限时抛出原始异常,绕过既有修复反馈;两个默认安装并发准备同一 Chat bundle 时产生目录重命名竞争。
改动思路
复用已有 errno 分类、终止回执和安装 guard。锁获取失败的原始错误保持终止性,即使后续 probe 已可写也不能无锁重试;默认安装先取得原 guard,再准备共享资源。未改变 promotion selector、权限、协议、状态格式或超时。
具体改动
sync_project_registry_to_global 仅捕获锁获取阶段的 EACCES/EPERM/EROFS;其他 IO 错误仍传播。成功调用仍在原锁内重读并归约;dry-run、source-is-global 和调用方持锁路径保留。install-local.sh 将已有 guard 移到 Chat ensure 前;canary-only 不创建默认 releases/guard。现有 smoke 增加真实权限恢复后的新调用/readback,以及实际委托锁、manifest、安装代码的准备观察。
对主干的风险
137 项 registry/source/codec/shadow/checkpoint/activation/operator 测试通过,相关真实 CLI sync/configure 与 POSIX deny/no-partial/recovery 通过。EACCES/EPERM/EROFS 后续 probe 可写仍拒绝写入,ENOSPC 不误分类。原始 base 上执行同一真实路径分别得到 PermissionError 和 pre-guard marker 失败,修复后通过。完整安装并发 smoke 验证不同 snapshot、manifest、普通/deep doctor、live/stale legacy lock 与无效候选保留旧默认;default/canary/skill 边界 smoke 通过。原60s guard 与120s child预算未调整。
变更 Python Ruff、canonical20-file 与 changed-module mypy、bash syntax、五路径 public boundary、exact-scope change-quality 与19项 native premerge 均通过。初始安装验证曾复制开发依赖导致超时;相同锁文件的忽略依赖缓存移出待安装源码,随后又独立重现实际 bundle race;两个问题与最终通过结果区分保留。测试 facade 初版没有执行全部安装 stdin,已修正为实际委托,最终证据来自修正后的完整安装。最终发布全量测试/真实模型/包分发资格尚在另行执行,不以本 PR 通过替代。
我的整体评价
这五路径修复在已有 owner 中完成两个已重现阻塞项,没有新增 reducer、锁、配置或能力。future-facing pass 已用于把资产准备和 promotion 纳入同一个已有操作边界,registry 继续共用错误分类与回执;无必要扩大模块重构。现有 CLI 回执/配置 readback 与安装入口已覆盖受影响用户路径,未改变 App/Lark 设置或首屏。可技术批准;必须满足仓库对 runtime/installer 的 maintainer 合并要求后才能进入发布来源。剩余风险是跨平台安装环境与最终发布工件,需要由后续冻结源码资格和真实分发 readback 单独验证。
b2ae4f3 to
7493952
Compare
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
English verdict: REQUEST_CHANGES - PR #5151 at 7493952. The denial and preparation-exclusion deltas are independently verified, but the original full concurrent-install validation is unresolved. The base/head failures have different signatures; a reduced dependency-copy workload does not erase them. This is an evidence hold, not a claim that the PR introduced a proven source defect.
动机
现有 sync-global 在锁获取阶段权限不足时会漏掉结构化拒写回执;默认安装的共享 Chat 准备又发生在 promotion guard 之外。这两个问题都有真实调用路径,本次复审检查完整五文件改动,基线为96a3b90f41094bd2ddea7263b9c7ee37371a9c3b,没有继承旧 head 的批准结论。
改动思路
复用现有 errno 分类、拒写回执和同一 release-root 的 flock。只捕获锁获取错误,保留函数执行及退出错误;把已有 guard 移到默认安装的共享准备之前。没有新增 CLI、持久化状态、协议或权限。保持现有60秒等待与120秒 smoke 子进程期限。
具体改动
| 定义 | 本次行为与核查 |
|---|---|
| loopx/global_registry.py:831 sync_project_registry_to_global | 获取锁失败走已有拒写回执;ENOSPC、上下文退出错误继续传播,正常写入仍持锁。 |
| loopx/global_registry.py:635 _sync_project_registry_to_global_once | 新诊断只作用于本次调用;修复权限后重新读取并真实持久化,不允许无锁重试。 |
| scripts/install-local.sh:125 run_under_install_guard;调用686–687 | 默认安装取得 guard 后才进入 Chat ensure;显式 canary0 和不受信任 auto 模式保留旧路径。 |
| examples/release/release-promotion-concurrency-smoke.py:220 | 实际启动两个安装、要求不同 release id,并读取已安装的 standard/deep doctor;此完整验收目前未通过。 |
独立运行的隔离缓存测试为 head132通过、base128通过,另有三个真实 registry 公共 smoke 通过。Ruff、仓库声明20项源文件的 mypy、global module 定向 mypy、bash-n、TS控制面 typecheck、diff检查及五路径公开边界扫描均通过。11个真实 registry 成对场景中6个完整结果一致,其余是结构化拒写以及“无效 Goal + 拒写”报错优先级的明确变化;真实 chmod 修复后重新同步和独立磁盘回读成功。3个安装模式的真实 held-flock 对照证明默认准备进入 guard,两个 canary 模式的完整观测保持一致。该两秒探针的主动取消只用于验证阻塞,不代表安装完成。六个原生 concurrency 阶段中另外五项有通过记录(含分开执行的候选拒绝及 archive manifest 来源);连续完整六阶段仍失败。五项 promotion-boundary 原生检查全部通过,包括实际显式安装及 doctor 回读、技能碰撞拒绝和既有默认保留。
对主干的风险
[P2] 完整并发安装的原始验证仍未归因。 在常规构建后的依赖目录存在时,新 head 的实际并发安装返回“timed out waiting for another local install to finish”(60秒 guard 等待);镜像相同实际依赖目录的 immutable base 则超过120秒子进程期限。失败身份不同,不能称作已证明的既有相同失败,也不能用移走依赖目录后的较轻测试抹去原始结果。
请补齐同一受支持 checkout 工作量的 base/head 归因及完整成功证据,保留原始期限和真正的安装/doctor 后置条件。若证实主要成本是先复制、后删除 node_modules 等无交付价值的开发依赖,可在现有 installer 边界消除该复制,再重跑;不应扩大期限或用 mock 替换最终验收。最小复验命令是 uv run --extra test python examples/release/release-promotion-concurrency-smoke.py,并读取两个 release manifest 与已安装 standard/deep doctor。
将开发依赖移到复制树外的补充运行也在同一60秒等待处失败,因此尚无证据将问题归因于依赖复制成本。原始共享 Effect RPC 缓存的测试另出现10秒 descriptor 超时,base/head 的失败测试ID不同,未宣称相同基线失败。独立 TMPDIR 缓存运行原命令后125/121项通过,另7项M0各通过;没有重置共享运行时。候选拒绝、默认保留和 canary 路径的补充测试单独记账,不能替代原始并发工作量。
补充预合并结果仍只针对7493952:19项选中检查18通过、1失败,另5项direct检查通过,无跳过或超时。install-local-smoke 的嵌套 manifest 来源断言在相同隔离环境的 immutable base/head 上返回完整一致的错误;两个因果源文件完全一致,失败发生在变更安装路径执行之前,按既有故障单独记录。strict change-quality 回执仍因原始并发安装验证未解决而失败,合并资格未取得。PR 随后 rebase 到46d6e8d652aab5a03b06d6eadc96e88c0771dca9 / base420782f03725bf9b7603be481f2b0525beff5807;三条补丁未变,但本评审及这些结果仅绑定旧 head,不自动移作新 head 的结论。
我的整体评价
五文件+115/-14的修复放在现有 owner 中,范围和复用合理;+27/-14为生产改动,其余是耐久回归覆盖。拒写恢复和准备互斥的价值已证明。未来相关简化检查发现了开发依赖“复制后删除”的具体成本,应据失败归因决定是否在本边界处理。
当前保留 REQUEST_CHANGES:需要的是上述实际安装验收与失败归因,不是更宽的全项目重构。没有声明全平台、全 release-root、混合 canary/default 并发或整次发布已完成,也不建议绕过 maintainer 合并门槛。
7493952 to
46d6e8d
Compare
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
English verdict: APPROVE
No blocking finding at 46d6e8d652aab5a03b06d6eadc96e88c0771dca9 against 420782f03725bf9b7603be481f2b0525beff5807. Runtime/installer merging remains a separate maintainer gate; this review does not grant that authority. GitHub CI was not consulted under repository policy.
动机
1.2.1 的真实发布验证重现了两个故障:global registry 的锁文件无写权限时抛出原始异常,绕过既有修复反馈;两个默认安装并发准备同一 Chat bundle 时产生目录重命名竞争。
改动思路
复用已有 errno 分类、终止回执和安装 guard。锁获取失败的原始错误保持终止性,即使后续 probe 已可写也不能无锁重试;默认安装先取得原 guard,再准备共享资源。未改变 promotion selector、权限、协议、状态格式或超时。
具体改动
sync_project_registry_to_global 仅捕获锁获取阶段的 EACCES/EPERM/EROFS;其他 IO 错误仍传播。成功调用仍在原锁内重读并归约;dry-run、source-is-global 和调用方持锁路径保留。install-local.sh 将已有 guard 移到 Chat ensure 前;canary-only 不创建默认 releases/guard。现有 smoke 增加真实权限恢复后的新调用/readback,以及实际委托锁、manifest、安装代码的准备观察。
对主干的风险
225 项 registry/source/codec/shadow/checkpoint/activation/operator 测试通过,当前源码的真实 CLI sync/configure 与 POSIX deny/no-partial/recovery 通过。EACCES/EPERM/EROFS 后续 probe 可写仍拒绝写入,ENOSPC 不误分类。在当前 immutable base 上执行同一真实路径分别得到 PermissionError 和 pre-guard marker 失败,修复后通过。完整安装并发 smoke 验证不同 snapshot、manifest、普通/deep doctor、live/stale legacy lock 与无效候选保留旧默认;default/canary/skill 边界 smoke 通过。两项安装 smoke 实际包含在最终候选122项公开验证窗口中,全窗口零失败;原60s guard 与120s child预算未调整。
变更 Python Ruff、canonical20-file 与 changed-module mypy、bash syntax、public boundary、exact-scope change-quality 与19项 native premerge 均通过。此前候选的失败和中止结果保留,未复用为当前候选资格;当前安装 fixture 使用相同锁文件的独立开发依赖缓存,原超时和判断标准不变。测试 facade 实际委托原锁、manifest 和安装代码。最终发布全量测试/真实模型/分发 readback 另行检查,不以本 PR 通过替代。
我的整体评价
这五路径修复在已有 owner 中完成两个已重现阻塞项,没有新增 reducer、锁、配置或能力。future-facing pass 已用于把资产准备和 promotion 纳入同一个已有操作边界,registry 继续共用错误分类与回执;无必要扩大模块重构。现有 CLI 回执/配置 readback 与安装入口已覆盖受影响用户路径,未改变 App/Lark 设置或首屏。可技术批准;必须满足仓库对 runtime/installer 的 maintainer 合并要求后才能进入发布来源。剩余风险是跨平台安装环境与最终发布工件,需要由后续冻结源码资格和真实分发 readback 单独验证。
The separate complete release smoke sweep executed522 scripts with521 passing and one status latency failure:6.33s against the unchanged3.5s budget on1200 ignored local files. This is an unresolved release qualification failure; this PR review does not approve release publication. Identical base/head workload diagnosis is pending.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Request changes conclusion (author-owned PR; GitHub blocks formal self-review)
English verdict: REQUEST_CHANGES - #5151 at b903eee, base 420782f. Refusal/recovery, the earlier preparation guard, UTF-8 reply decoding and the refreshed IO census are independently checked. Complete native concurrent installation still fails; the same baseline error does not by itself exclude a change to the guarded interval. This is a validation hold, not a proven introduced defect.
动机
本次重审完整七文件改动,不继承46d6e8d的批准。目标是修复 global registry 锁获取时漏掉拒写反馈,以及默认安装在 guard 外准备共享 Chat 资源的问题。新提交还修复 Node 回复依赖系统 locale 的解码,并更新既有 IO 清单。评审依据是现有安装失败矩阵,不是整次发布已完成的声明。
改动思路
拒写路径复用现有 errno 分类、回执和 global registry reducer;ExitStack 只捕获锁进入阶段,执行和退出错误继续传播。默认安装复用同一 release-root 的已有 flock,先取得 guard 再准备 Chat。usage transport 指定 UTF-8,权限与采集政策仍由原 TypeScript owner 决定。没有新增 capability、协议、持久状态、配置或超时;canary 仍走现有独立路径。
正向真实路径已验证:chmod 拒写后,恢复权限并发起新 sync 能持久化,随后重复同步和独立磁盘回读正确;完整 native 的首个 held-guard 安装通过。两条 canary 安装在默认 guard 全程持有时仍完成,默认文件不变,完整 doctor/readback 与 base 一致。
具体改动
关键代码讲解
| 符号 | 本次行为与证据 |
|---|---|
| global_registry.py:831 sync_project_registry_to_global | 只把获取锁时的 EACCES/EPERM/EROFS 转为已有拒写回执;ENOSPC 和上下文退出错误保留。健康写入仍持锁。 |
| global_registry.py:635 _sync_project_registry_to_global_once | 当前获取错误是本次调用的诊断,后续 probe 可写也不能无锁重试;dry-run、caller-held、global-source no-op 保留。 |
| install-local.sh:125 run_under_install_guard,调用689 | 原60秒等待、继承锁 fd 和 exec 不变,调用提前到703行 Chat ensure 之前;显式 canary 与不受信任 auto 不获取默认 promotion 权限。 |
| usage_ping.py:52 control | Node stdout/stderr 固定按 UTF-8 解码,4秒期限与 TS 状态 owner 不变;CLI 和 Chat 共用此修复。 |
两个 smoke 增加实际权限恢复,以及真正委托锁、manifest、安装代码的 preparation 观察;新四项 errno 测试验证拒写终止性和 ENOSPC 传播。IO 清单只补齐当前 authority_archive、usage_goal 两个已有 codec 调用与行号,未缩小扫描根或移除规则。七文件共+141/-24,其中生产+28/-15、回归覆盖+88、清单+25/-9。相对上个批准 head,新加的是 transport codec 和清单两文件,全部七文件仍独立复查。
11个 registry 成对场景中6个完整结果一致;其余明确变化为结构化获取拒写及“未知 Goal + 拒写”时源校验优先,均无写入。16个真实 Node locale 对照中13个完全相同,另3个 ASCII locale 的 Unicode 诊断在 base 抛出 UnicodeDecodeError、head 正确返回,未激活采集且文件字节不变。临时路径、时钟及 write-probe 中 PID 是唯一比较归一化;未删除诊断、字段或错误身份。早期 locale 探针使用了无效 fixture,不计入这些证据,已更正为当前 v1/UUID fixture 后重跑。
对主干的风险
[P2] 完整并发安装仍未取得可交付结果。 原命令 uv run --extra test python examples/release/release-promotion-concurrency-smoke.py 在 head 和当前 immutable base 都于 concurrent-release 断言返回 guard 等待超时。两边依赖锁相同,实际开发依赖目录均12587个普通文件、169981870字节;保留原60秒 guard 和120秒子进程期限。head 整个失败运行181.9秒,base167.9秒;它们包含不同冷/热准备阶段,不能把总时长差当成本次回归证据。
同一失败身份补齐了上轮缺失的基线对照,但这次修改正好涉及 guard 内的准备区间,所以尚不能证明它与改动无关,也没有证明本次引入了新缺陷。请在同一受支持 checkout 工作量上给出 preparation、copy/cleanup、doctor 与 guard 持有时间的归因,以及两次真实安装、不同 release manifest、已安装 standard/deep doctor 的完整成功证据。若确认复制后删除开发依赖是主因,应在现有 installer owner 中作有界修复;不应移走依赖后覆盖原失败、扩大期限或用 mock 替代安装后置条件。
语义与 CI 对齐
本次 head 94项选中原生测试全通过;base89项通过,另1项旧清单不完整失败,被本次 census 更新修复。Ruff、声明20源文件与改动模块 mypy、TS typecheck、bash syntax、diff 检查及五个 commit 的 DCO 通过。promotion-boundary 完整 smoke 和三个真实 registry smoke 通过;源码七路径公开边界扫描零错误,两个既有 Goal-state 警告与本 diff 无关。两个 canary 的完整 doctor 和状态成对一致;两秒取消探针只证明 exclusion,未算作完成安装。按 Goal 当前 wait_for_ci=false 没有读取或等待 GitHub CI。
同一 exact-head 的 change-quality receipt 已记录 required validator 失败;strict receipt 校验阻止通过,goal-aware premerge 只读检查返回 quality_invalid_receipt,未执行其19项完整检查。该只读结果另标记一个与改动文件无关的既有 maintainability advisory,未将其升级为本 diff blocker。
这些通过结果不能替代上述原始完整 concurrency 失败。新增拒写、UTF-8 与清单语义复用现有词汇;并发两安装完成这一现有验收行仍未满足,不能凭作者全量通过声明或旧 head 评审跳过。跨平台、跨 release-root、混合 canary/default 并发与整个发布资格仍未声明完成。
我的整体评价
范围、复用与维护成本合理,没有证据要求新增框架或整体语言重写;未来相关简化检查已将 preparation 与 promotion 归到同一已有 owner,并指出复制后删除依赖这一应按测量决定的潜在成本。拒写恢复、canary 隔离和 transport 修复有真实价值,但 long_horizon 与 user_experience 的两个默认安装持续完成仍未证明,因此当前结论为 REQUEST_CHANGES。最小后续是补齐上面的归因和实际安装验收,保持安全锁、原预算与 maintainer 合并边界。
| if [[ "$promote_default" == "1" ]]; then | ||
| # Preparing shared Chat assets is part of the guarded installation. | ||
| mkdir -p "$releases_dir" | ||
| run_under_install_guard "$@" |
There was a problem hiding this comment.
[P2] Complete concurrent-install acceptance remains unqualified at this head. The original native smoke fails with the 60-second guard timeout on both current base and head, using the same locked dependency workload and original 120-second child deadline. Because this call moves preparation into the guarded interval, identical errors alone do not establish unaffected guard residence or two-install completion. Please attribute preparation, copying/cleanup and doctor costs under the same supported workload, then show both real installs, distinct release manifests and installed standard/deep doctor succeed. This is an evidence hold, not a proven introduced defect; preserve the original budgets and failed sample.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Problem and result
Qualification for v1.2.1 exposed failures in existing registry, installer and usage paths. Registry lock denial escaped the established repair receipt; concurrent installers prepared shared Chat assets before taking the promotion guard; usage replies depended on the parent locale; and competing detached usage observers could persist a daily heartbeat claim without initiating its request. The generated registry IO census also needed to reflect current accepted source reads.
This change restores actionable permission feedback, serializes shared installation preparation, explicitly decodes Node replies as UTF-8, and initiates a daily heartbeat under the same short lock that persists its claim. Network waiting remains outside that lock. The existing AST generator refreshes the IO census without changing classification.
Implementation
No new capability, provider, payload field, schema, permission, activation setting or network queue is introduced. The existing CLI/settings readback remains the user entry point. The related simplification removes the redundant heartbeat acquisition and makes shared installer preparation part of its existing serialized operation.
Validation
At
3c1320b29987f16a9ab3f86d50a63212034e851c, 41 focused Python tests and 22 usage TypeScript tests pass, including real HTTP/proxy/NO_PROXY, disable while a request is in flight, old-generation rejection, separate aggregates and no retry. An immutable baseline reproduces the lost daily claim under the same controlled real filesystem-lock scheduling; the head initiates exactly one request and does not repeat that day. Actual POSIX denial, no partial connect/registration, fresh sync after permission repair, and CLI sync/configure pass. A real Node pipe comparison reproduces baseline UnicodeDecodeError and correct head decoding.Ruff, mypy, TypeScript typecheck, shell syntax, IO census checks and public boundary scanning pass. The complete frozen-source release qualification is running again; earlier failed candidates remain failed and are not used as current passing evidence. Public artifact, PyPI and desktop distribution readback will follow publication. GitHub CI is not consulted under the selected review policy.
Merge boundary
This PR changes runtime and installation behavior, so merge remains subject to the repository's maintainer authorization rule and a published review on this exact head. It does not claim that v1.2.1 has been published.