Repository navigation
fix(cli): 同一时间戳刻度内新增的目录项不再被缓存漏掉;插件安装测试改用可执行临时目录 - #85
Merged
Merged
Conversation
…an executable temp dir Command-local directory listings were keyed on the directory's dev, inode, size, mtime and ctime. File systems advance timestamps in coarse ticks (ext4 by kernel tick), so adding an entry in the same tick as an earlier change left the stamp equal and a later read in the same command missed the new file. Like Git's racily-clean rule, a listing whose directory changed within the last second is now never reused. File reads keep their reuse: Context replaces files atomically, so a change gets a new inode. Plugin install tests put fake claude/codex executables on PATH under the system temp directory, which hardened hosts mount noexec. They now probe once and fall back to the ignored package-local .tmp/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Summary
修复长期存在的 4 个测试失败。其中 2 个暴露的是真实缺陷:同一命令内,目录在同一个文件系统时间戳刻度内新增文件时,后续读取看不到新文件。另外 2 个是测试在
noexec的系统临时目录里执行假的宿主 CLI。不改版本号,随下一个版本发布。Compatibility
无数据或接口兼容影响。目录列表在目录最近 1 秒内有改动时不再复用缓存(重新
readdir),其余文件读取的复用行为不变。Verification
见下方「自测情况」。
Checklist
bun run verify:fullpasses.(本地跑了 lint 与 context-cli 全量bun test,见自测情况)背景
在开发环境中,以下 4 个测试在未修改的
main上稳定失败:statusReadCost:command reads share bytes but detect additions…productionReadReuse:shared directory reads observe nested additions…(时好时坏)cli:plugin install continues available agents when codex is missingcli:plugin install replaces an existing Claude plugin…目录缓存(真实缺陷):命令内目录列表以目录的 dev/ino/size/mtime/ctime 作为缓存戳。文件系统按粗粒度刻度推进时间戳(ext4 按内核 tick),同一刻度内新增文件不会改变任何一项;ext4 目录大小也保持 4096。实测在 ext4 上连续新增文件,200 次中有 195 次目录戳完全不变,因此同一命令里随后的读取会复用旧列表,漏掉新文件。CI 通过只是因为时序不同。
插件安装测试(测试环境假设):测试把假的
claude/codex写到os.tmpdir()并放进 PATH;系统临时目录挂载为noexec时启动失败(EACCES: posix_spawn 'claude')。改动
commandReadCache.ts:reuseCommandFileRead新增racyWindow选项,目录列表(readCommandDirectory)启用。与 Git 的 racily-clean 规则相同:路径的 mtime 在读取前 1 秒内时,该次读取不被复用。文件读取不启用:Context 以原子替换写文件(新 inode),已有戳足以发现修改,同一命令内对刚写入文件的复用与并发合并保持不变。statusReadCost.test.ts:新增回归用例,在同一命令内连续新增 50 个文件并逐次断言列表长度。cli.test.ts:新增executableTmpdir(),先在系统临时目录试运行一个探测脚本,不可执行时改用包内已忽略的.tmp/cli-exec-tests;三个放置假 CLI 的插件安装测试改用它。风险
目录在最近 1 秒内有改动时,同一命令内会多做几次
readdir;只影响刚被修改的目录,开销很小。向后兼容
无行为兼容影响;CLI 输出与 JSON 不变。
自测情况
statusReadCost、productionReadReuse、commandReadCache、commandReadConsumers、projectWriteLockV0618全部通过(连续 3 次);cli.test.ts29 pass。bun test:1365 pass,1 fail。失败的是负载下的超时用例(projectKnowledgeUpdate,5 秒超时),单独运行 3 次均 17/17 通过,与本改动无关。🤖 Generated with Claude Code