chore(发布): 准备 0.7.15 - #67
Merged
Merged
Conversation
未 push 的开发线不再把 next/start 卡成 needs_repair;task close 拒绝符号链接工作树;dry-run 与复核拒绝按契约执行。
task loop/daemon 在复核失败时非零退出;事件追加失败标记 overlay 不完整;merge --dry-run --push 改为真实预检。
把 feat/dev_0814 上的控制面诚实性与任务关闭收口收进 0.7.13。 版本停在 0.7.x,不改 0.7.12 历史,不发明新功能。
next / Console 在仅缺 origin/<branch> 时保持 ready;测试改为断言 WARN 契约。
doctor() 原先对每个 (开发线, 仓库) 组合串行发约 8 条 git 命令。慧衣橱工作区
(5 个仓库 × 13 条开发线)一次需要 399 次子进程调用、耗时 5.6s;首页菜单与
开发线准入闸门各跑一轮,进一条开发线约 11s。
改为按仓库预取两份观测:
- git worktree list --porcelain 一次取回该仓库全部 worktree 的路径、HEAD 与
分支,取代逐 worktree 的 branch --show-current、rev-parse HEAD 以及成对的
rev-parse --git-common-dir。出现在这份清单里本身就是共用 Git 公共目录的
证据。
- git for-each-ref refs/heads refs/remotes/origin 一次取回每个本地分支的上游
与每个引用的对象 ID,取代逐开发线的 show-ref、rev-parse origin/<branch> 与
rev-parse @{upstream}。
worktree 不在清单里时回退到原有的单次探测,"missing worktree" 与
"unexpected Git common-dir" 两种诊断仍可区分。ReadBudget 的字节计费与 deadline
照常穿透,观测点由每条开发线移到每个仓库。
慧衣橱工作区的调用次数由 399 降到 16,耗时由 5.61s 降到 0.30s;四个真实工作区
的 findings 列表(含顺序)与改动前逐条相同。
测试故障注入点 _raise_deadline_on_worktree 同步扩展为「路径含 versions/ 或为
git worktree 调用」,新旧两版代码均通过,被测不变量未变。
把版本号推进到 0.7.14,并同步所有与版本绑定的断言与资产: `pyproject.toml`、`uv.lock`、bridge skill 的 client version,以及 `test_cli`、`test_console_artifacts`、`test_release_gates` 中的版本断言。 CHANGELOG 记录本版唯一的对外改动:doctor 改用批量 Git 观测。 `uv lock` 在更新项目版本的同时,把 `importlib-metadata` 对 `zipp` 的依赖 标记收紧为 `python_full_version < '3.14'`。这是本机 uv 重解析出的上游 metadata 修正,没有任何包版本变化。 本地锁定验证:`uv lock --check`、`uv sync --locked --all-extras --dev`、 `ruff check src tests experiments`、`python -m build`、 `twine check --strict` 全部通过。
`cli.py` 在模块作用域 import `console.launcher`,把 inspection、events、
overview 整条链拉进每一次 `dyro` 启动,而它只有 `cmd_console` 用得到。
改为在 `cmd_console` 函数体内 import,与 `home.py` 既有写法一致。
实测收益有限:空闲机器上 `dyro.cli` 的累计 import 时间由 225-236ms 降到
210-216ms,约 20ms。`-X importtime` 给 `console.launcher` 记的 81ms 是含
子树的累计值,而 console 的下游(`continuation.*`、`observations`)本来
就被 cli.py 的其他依赖拉入,摘掉 console 摘不掉它们。验证 `dyro.console`
已完全不在启动 import 图中。
`tests/test_hub.py` 的 `patch("dyro.cli.launch_console")` 随之改为 patch
源模块 `dyro.console.launcher.launch_console`。延迟导入在调用时才解析属性,
patch 源模块对 eager 与 lazy 两种写法都成立。
全量 1123 条测试,失败集合与改动前基线一致,无新增失败。
`RunStore.load` 经 `_read_payload` 读运行状态文件时,先 `os.open` 拿到 fd,再 `os.stat(path, follow_symlinks=False)` 复查,用 `os.path.samestat` 比对 inode。写入侧 `_save_unlocked` 走 `atomic_write_json`,以 `os.replace` 发布更新。读取侧 `load` 不持锁,因此异步 worker 的一次合法 更新若落在 open 与复查之间,inode 就会变化,守卫抛 `DispatchValidationError`,`cli.py` 将其转为退出码 2,运行随之失败。 这不只是测试偶发:任何在 worker 更新状态时并发读取的真实 dispatch 运行 都可能踩到。CI 上表现为 test_default_cli_run_starts_async_worker 间歇性 失败,stderr 为 `run state path changed while opening: run-...`。 单次读取抽出为 `_read_run_state_bytes`,inode 不匹配时返回 None; `_read_payload` 有界重试 `RUN_STATE_REOPEN_ATTEMPTS` 次,用尽后仍按原有 语义拒绝。合法的 `os.replace` 一两次即稳定,持续变化的路径依旧被拒。 安全属性未放宽:`O_NOFOLLOW` 在每次尝试上生效,`fstat` 仍校验普通文件与 大小上限,符号链接仍拒绝,读取仍只走已打开的 fd。可重试的只有「仍是打开 时那个 inode」这一项,因为合法原子写入触发它的方式与路径掉包完全相同。 若文件被换成符号链接,重试时 `O_NOFOLLOW` 以 ELOOP 失败,报出更准确的 `run state is a symbolic link`。 新增两条回归测试:一条在 open 与复查之间真实执行 `atomic_write_json`, 断言读取成功且拿到更新后的内容;一条每次尝试都替换,断言仍然拒绝且用满 重试次数。把 RUN_STATE_REOPEN_ATTEMPTS 置为 1 时,前者复现出与 CI 一致的 报错,确认该测试能抓到本缺陷。 全量 1125 条测试,失败集合与改动前基线一致;ruff src tests experiments 通过。
main 上的 #66 以 squash 方式合入,本分支与 main 再次同容不同史。合并前 已确认 git diff origin/main HEAD 只含本分支尚未发布的 4 个文件,main 不 含本分支缺少的内容;冲突解析取本分支侧,合并后树与合并前 HEAD 相同。
把版本号推进到 0.7.15,并同步所有与版本绑定的断言与资产: `pyproject.toml`、`uv.lock`、bridge skill 的 client version,以及 `test_cli`、`test_console_artifacts`、`test_release_gates` 中的版本断言。 CHANGELOG 记录本版两条对外改动:dispatch 运行状态读取不再把原子写入误判 为路径掉包(修复 `dyro dispatch` 偶发退出码 2),以及 console 子系统改为 延迟导入。 本地锁定验证:`uv lock --check`、`uv sync --locked --all-extras --dev`、 `ruff check src tests experiments`、1125 条测试、`python -m build`、 `twine check --strict` 全部通过;测试失败集合与本版改动前的基线一致。 `uv lock` 期间 PyPI 连接超时,改用 `--offline` 完成。本次只有项目版本号 变化,依赖已解析并缓存,lock diff 仅一行,`uv lock --check` 复核通过。
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
本版两条对外改动
1.
dyro dispatch不再因并发读取运行状态而偶发失败RunStore.load经_read_payload读运行状态文件:先os.open拿 fd,再os.stat(path, follow_symlinks=False),用os.path.samestat比对 inode。写入侧_save_unlocked走atomic_write_json,以os.replace发布更新;读取侧不持写锁。异步 worker 的一次合法更新若落在 open 与复查之间,inode 就变了,守卫抛DispatchValidationError,cli.py转成退出码 2。症状是
dyro dispatch run间歇性失败,stderr 为run state path changed while opening: run-<id>。这不只是测试偶发:任何在 worker 更新状态时并发读取的真实运行都可能踩到。单次读取抽出为
_read_run_state_bytes,inode 不匹配返回None;_read_payload有界重试RUN_STATE_REOPEN_ATTEMPTS(5)次,用尽后仍按原语义拒绝。合法的os.replace一两次即稳定,持续变化的路径依旧被拒。安全属性未放宽:
O_NOFOLLOW在每次尝试上生效,fstat仍校验普通文件与大小上限,符号链接仍拒绝,读取仍只走已打开的 fd。可重试的只有「仍是打开时那个 inode」一项,因为合法原子写入触发它的方式与路径掉包完全相同。文件被换成符号链接时,重试以ELOOP失败,报出更准确的run state is a symbolic link。2. console 子系统改为延迟导入
cli.py在模块作用域 importconsole.launcher(其后是 inspection/events/overview),而只有dyro console用得到。移入cmd_console函数体,与home.py既有写法一致。实测收益有限:
dyro.cli累计 import 由 225-236ms 降到 210-216ms,约 20ms。-X importtime给console.launcher记的 81ms 是含子树累计值,而 console 的下游(continuation.*、observations)本来就被 cli.py 的其他依赖拉入。已确认dyro.console完全不在启动 import 图中。验证
新增两条确定性回归测试(
ProcessAndLifecycleTests):test_run_state_read_survives_a_concurrent_atomic_replace— 在读取者os.open之后、inode 复查之前真实执行一次atomic_write_json,断言读取成功且拿到更新后的内容test_run_state_read_still_refuses_a_path_that_keeps_changing— 每次尝试都替换,断言仍然拒绝且用满重试次数把
RUN_STATE_REOPEN_ATTEMPTS置为 1(等价修复前)时,前者复现出与 CI 一字不差的run state path changed while opening: run-...,确认该测试能抓到本缺陷。tests/test_hub.py的patch("dyro.cli.launch_console")随延迟导入改为 patch 源模块dyro.console.launcher.launch_console,对 eager / lazy 两种写法都成立。本地锁定验证:
基线上既有的两条环境敏感失败(
test_inspect_timeout_reaps_hung_descendants、test_legacy_board_status_stays_on_protocol_id)与本次改动无关,无新增失败。发布准备
按
docs/publishing.md同步了全部 7 处版本绑定。uv lock期间 PyPI 连接超时,改用--offline完成;本次只有项目版本号变化,lock diff 仅一行,uv lock --check复核通过。合入后需要在
main的对应 SHA 上打v0.7.15、创建 GitHub Release。