Repository navigation
fix: harden Windows process ownership, lock cleanup and root validation - #47
Conversation
Bind Windows tree termination to verified native handles and preserve incomplete cleanup evidence across recovery, retries, and worker commits. Harden filesystem lock transitions, late identity writes, and repository root guards. Add lifecycle regressions, ADR-009, and synchronized bundles. Validation: Windows Node 22/24 and isolated Linux Node 24 matrices, identity and recovery counterexamples, and owned process-tree tests. The staged sources match the independently accepted source manifest.
|
对当前 head P1:枚举后消失的记录 PID 会漏掉存活子进程位置: 枚举中存在父 101 和仍存活的子 102;随后 建议在 absent 分支保守失败,或正确更新状态并继续追踪旧父名下的存活子代,不能用过期的 live 集合证明清理完成。 P1:父 PID 换代不代表旧代子进程已经退出位置: 记录的原父 101 指纹为旧代;扫描时 101 已被新进程复用,但旧子 102 仍存活,且创建时间早于新父。当前实现把 101 标为 foreign 后排除整棵树,仍返回 建议只排除有证据属于新代的后代;旧代或不可归属的候选继续保持占用。现有“新父+新子”的排除测试不能覆盖“新父+存活旧子”。 这两处返回值会进入 Manager 的 cleanup release gate,可能提前清除 可独立重跑的最小反例先运行 import { verifyWindowsRecordedTreeClaimants } from './dist-test/src/adapters/windows-process-cleanup.js';
const row = (pid, parentPid, t) => ({
pid, parentPid, creationFileTime: String(t), startTicks: String(t),
});
for (const scenario of ['absent-after-enumeration', 'reused-parent-old-child']) {
const absent = scenario === 'absent-after-enumeration';
const tx = {
enumerate: async () => absent
? [row(101, 4, 100), row(102, 101, 200)]
: [row(101, 4, 300), row(102, 101, 200)],
hold: async () => absent
? [{ pid: 101, status: 'absent' }]
: [{ pid: 101, status: 'ok',
creationFileTime: '300', creationTicks: '300' }],
close: async () => {},
kill: async () => { throw Error('read-only probe must not signal'); },
};
const result = await verifyWindowsRecordedTreeClaimants(
[{ pid: 101, fingerprint: '100' }],
{ open: async () => tx },
);
console.log(scenario, result);
if (result.clean) process.exitCode = 1;
}本次验证与待核实项
与维护者本地改动的整合边界ENOTEMPTY/EPERM 锁竞争处理、worker fixture 退出后再删目录,与维护者本地修复部分重复。锁释放机制是互补的:本 PR 做有限撤回重试,本地以 token 绑定的 双方还使用了不同内容的 ADR-009,需要整合时重编号并同步引用;无需在本 PR 顺带实现维护者的其他本地功能。 请先修改本 PR 的两处 P1、补回归并排查上述本机测试失败,更新后再审。维护者本地改动暂不合并,本 PR 也先保持未合并。 |
Changes
Harden filesystem root guards, lock cleanup and Windows process ownership, including the claimant-scan failures reported against
628984c.Verification
Independent verification of the repaired candidate:
Typecheck, build, plugin validation, clean-entrypoint checks and diff checks passed. Independent positive/negative scanner probes and real Manager consumption/recreation tests passed on Node 22.18.0 and 24.16.0. Original failing candidates and intermediate failures were retained. Linux ran rootless, non-root, without networking or host mounts, with capabilities dropped and no-new-privileges enabled.
The initial Linux bundle comparison differed only in source-path comments because the evaluator linked its dependency directory. Build-only checks using physical dependencies on both runtimes produced byte-identical candidate bundles; full suites were not repeated.
Boundaries
The maintainer's two process-lock failures were not naturally reproduced locally, including with Node 24.16.0. The budget correction has deterministic regression evidence; this does not establish the exact cause on the maintainer's machine. Unobserved intermediate ancestors remain outside the scan's proof. Platform/version-specific skips are retained rather than reported as passes. ADR-009 numbering remains subject to integration coordination. No dependency, public MCP schema, release or installed-plugin update is included.
See the repair report and ADR-009 for the final behavior and evidence boundaries.