Skip to content

fix(bash-ipc): retry a transiently refused quarantine (#352) - #354

Merged
T-Auto merged 3 commits into
T-Auto:mainfrom
Richeir:fix/bash-ipc-quarantine-retry
Oct 21, 2026
Merged

T-Auto merged 3 commits into
T-Auto:mainfrom
Richeir:fix/bash-ipc-quarantine-retry

Conversation

@Richeir

@Richeir Richeir commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator

Closes #352

What was wrong

bash-ipc 把校验通过的 MSYS 运行时缓存在 $DSH_HOME/dsh-ops/bash-ipc/<id>。一旦某个 generation 校验失败,confinedBash 会先把它重命名成 <id>.bad-<base36> 隔离,再重新 staging 一份;这个重命名是单次 fs.renameSync,第一次被拒就是终局:

FAIL a tampered cached generation is rejected, quarantined and rebuilt
  Error: Bash IPC runtime at ...\bash-ipc\213d... failed verification and could not be quarantined (EPERM: operation not permitted, rename '...213d...' -> '....bad-mvhlnfps'). Stop any confined shell, then delete that directory and retry.

在 Windows 11 26100 上,树刚写完的约 1.5 秒内这条 rename 会被拒,之后就能成功——换另一个进程也一样,且本机实时防病毒是关闭的:

run 0: first attempt EPERM at +1ms  -> ok after 1639ms (attempt 27)
run 1: first attempt EPERM at +2ms  -> ok after 1476ms (attempt 24)
run 2: first attempt EPERM at +2ms  -> ok after 1467ms (attempt 24)

于是恢复路径把一个片刻后就消失的条件报成了"无法隔离",bash-ipc 套件在本机确定性变红(修复前 3/3),提示语还让用户去停一个根本没在跑的 shell。

复现:npm ci --ignore-scripts && npm run build:ptc && npm run build:bash-ipc && node test/run.mjs bash-ipc。

The change

  • src/bash-ipc.ts:新增 renameWithRetry(),只对 EPERM/EBUSY/EACCES 做 100/200/400/800 ms 的有界退避(合计 1.5 s,即实测窗口);其它错误码、以及最后一次退避之后的失败,仍然立刻抛出。发布用的 rename(stage → target)走同一个助手。
  • 隔离动作抽成 quarantineGeneration(),保留原有"只留最近两份"的清理与日志;错误文案改为 "could not be quarantined after retrying",并把剩余原因写成"有受限 shell 或其它进程仍在使用"。
  • test/bash-ipc.test.mjs:renameWithRetry 补单测(两次拒绝被吸收、ENOENT 只试一次、尝试次数等于 delays + 1);quarantineGeneration 用注入的瞬时 EPERM 断言隔离最终完成(生成同级隔离目录、原目录消失),再用永久拒绝断言尝试次数恰为 RENAME_RETRY_DELAYS_MS.length + 1 且目录保持原样。
  • docs/CHANGELOG.md:## [Unreleased] 双语条目。

刻意没做:没有改动"校验通过"的判定,没有新增依赖,没有改变隔离保留份数;重试也不在每命令热路径上——只有 generation 已经校验失败时才会走这里。rename/wait 可注入,只是为了让测试能构造确定性失败,而不用真的睡 1.5 秒。

Validation

  • 本 PR 有一次 pull_request 事件触发的 CI required run,URL 见下方代码块
  • npm run verify 的实际输出(见代码块)
  • 撤掉本次实现后相关检查变红(行为级,见下方红绿对照)
  • docs/CHANGELOG.md 的 ## [Unreleased] 已加条目
  • 行为变化已同步相关 docs(未改动面向模型的描述、schema 与提示词字节)
  • 未新增依赖,未改 package.json 的版本与 optionalDependencies
$ node test/run.mjs bash-ipc
dsh-ops bash-ipc: all 8 checks passed
dsh-ops test: 1 suite(s) passed in 52s

$ npm run verify
dsh-ops test: 122 suite(s) passed, 4 skipped in 343s          # 退出码 0

$ npm run typecheck
(无输出,退出码 0)

$ npm run check:size
check-file-size: 383 code file(s) checked, all at or under 1000 lines (longest: bench/setup/profile.mjs (924))

$ gh run view <run-id> --json url,event,conclusion --jq '"\(.url) \(.event) \(.conclusion)"'
<CI required 的 run URL,event 必须是 pull_request>

红绿对照:把 RENAME_RETRY_DELAYS_MS 临时改成 [](等价于单次尝试)并重建,两条检查立刻变红——既有那条篡改用例(真实 EPERM 窗口)和新加的注入用例:

$ node test/run.mjs bash-ipc
  FAIL a tampered cached generation is rejected, quarantined and rebuilt
  FAIL a transient EPERM on quarantine is retried instead of stranding the cache (#352)
dsh-ops bash-ipc: 2 of 8 check(s) failed

4 个 skip 都是平台性的:linux-attributes 与 linux-shell 是 POSIX 概念,两个 TUI 套件需要 DSH_OPS_TUI_ROOT。

Environment

  • Windows x64 —— Windows 11 专业版 10.0.26100(build 26100)
  • Node v24.11.0,npm 11.12.1
  • 基于上游 main 的 a9ff940(0.4.1);安装通道:源码检出,npm ci --ignore-scripts(安装 @dsh-ops/[email protected])、npm run build:ptc、npm run build:bash-ipc

@Richeir
Richeir marked this pull request as ready for review October 21, 2026 05:29
@Richeir Richeir changed the title [Draft] fix(bash-ipc): 缓存隔离遇到瞬时 EPERM 时重试,而不是直接失败 (#352) fix(bash-ipc): 缓存隔离遇到瞬时 EPERM 时重试,而不是直接失败 (#352) Oct 21, 2026
@T-Auto T-Auto changed the title fix(bash-ipc): 缓存隔离遇到瞬时 EPERM 时重试,而不是直接失败 (#352) fix(bash-ipc): retry a transiently refused quarantine (#352) Oct 21, 2026
@T-Auto
T-Auto merged commit 3742da3 into T-Auto:main Oct 21, 2026
9 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

Development

Successfully merging this pull request may close these issues.

[BUG][Low] bash-ipc 在 Windows 上隔离被篡改的运行时缓存时会撞上瞬时 EPERM,恢复路径直接失败

2 participants