fix(windows): conditional DACL re-stamp + damaged-children repair, gated on the adoption-level owner-only predicate - #1685
Merged
Conversation
Re-stamp the runtime DACL only when it is actually wrong, and repair cache children left unusable by the pre-v0.10.3 DACL regime. The unconditional per-start re-stamp rewrote an already-correct security descriptor and propagated it to children (#1601 counted eleven no-op "Security change" USN records against one _config.db in a day), and every rewrite is a window in which a concurrent atomic publish can be refused DELETE on the destination (#1620). The old regime's PROTECTED, non-inheritable ACE also left every child born unusable — the 0-byte worker-log class behind #1416's diagnosis — so the secured directory now walks its regular children and repairs any with an empty DACL or a foreign owner. The fast path is gated on the ADOPTION-level predicate, not the general secure() check: lock-directory adoption (private_win_owner_only_dacl) demands the exact protected owner-only single-ACE descriptor the stamp writes, while secure() also admits SYSTEM/Administrators ACEs. A fresh directory with an inherited DACL passed secure(), skipped the stamp, and stranded every subsequent lock adoption — 59/77 daemon-suite failures on the real Windows VM. With the ported predicate (SE_DACL_PROTECTED, single non-inherited owner ACE, FILE_ALL_ACCESS/GENERIC_ALL) the same VM runs 77/77 and the full suite 7346/0. Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This was referenced Aug 17, 2026
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.
Supersedes #1634 and #1636 (same commits, rebased onto current main, plus the fix their Windows CI failures were pointing at).
The stack (unchanged in intent): re-stamp the runtime DACL only when it is actually wrong (#1634 — stops the daily USN "Security change" storms of #1601 and the MoveFileEx refusal window of #1620), and detect/repair cache children left unusable by the pre-v0.10.3 DACL regime (#1636 — the 0-byte-unreadable-log class behind #1416's diagnosis).
What the old PRs' red CI was: real. On the actual Windows VM the branch failed 59/77 daemon-suite tests (main: 77/77). Root cause, found by instrumenting the VM build: the conditional-re-stamp fast path declared a directory "already correct" using the general secure() predicate — which admits SYSTEM/Administrators ACEs — while lock-directory ADOPTION (
private_win_owner_only_dacl) demands the exact protected owner-only single-ACE descriptor the stamp writes. A fresh runtime dir with an inherited DACL skipped the stamp and stranded every subsequent lock adoption. The fast path now applies the consumer's strictest predicate, ported ACE-for-ACE (SE_DACL_PROTECTED, non-inherited single ACE, owner SID, FILE_ALL_ACCESS/GENERIC_ALL), so it skips work only when skipping is safe.Verification (real arm64 Windows 11 VM): the three canary suites went 18/59-failed → 77/77; full
test-par7346 passed, 0 failed (onegrammar_probe_c900s wall-clock hang, cleared on retry — the known grammar_probe flake family, pre-recorded). macOS + Linux compile the POSIX paths untouched.🤖 Generated with Claude Code
https://claude.ai/code/session_018RiRAw9RQhvCoshqe7eZHV