Repository navigation
feat(native): Windows no-replace publication of the socket secret - #4310
Open
code-yeongyu wants to merge 5 commits into
Open
code-yeongyu wants to merge 5 commits into
code-yeongyu wants to merge 5 commits into
Conversation
code-yeongyu
marked this pull request as ready for review
October 26, 2026 01:25
code-yeongyu
force-pushed
the
feat/4199-native-no-replace-publish
branch
from
October 26, 2026 04:26
b75492c to
39262f7
Compare
code-yeongyu
force-pushed
the
feat/4199-native-no-replace-publish
branch
from
October 26, 2026 07:43
91397f5 to
6af9812
Compare
Adds publish_no_replace to crates/senpi-socket-secret: a CREATE_NEW same-directory staging file with a protected owner-only DACL, written in full and flushed, then renamed with FileRenameInfo ReplaceIfExists=FALSE. A destination collision returns Collision for the caller to read the winner; every other failure keeps its own step and Windows error, and staging is deleted through its own handle. Native receipts cover first publication, collision (also with an open reader), a 16-way race with exactly one winner, a pre-existing staging name, and the DACL. Part of sisyphuslabs/omo-desktop-app#4199
…ndle Review fold for senpi#4310 (review-4310-r1): - M1/M2/L6: the staging file is opened once with GENERIC_WRITE | DELETE (share read only), written, flushed and renamed through that handle; on any outcome but Published the same handle deletes it. Nothing is reopened or deleted by path, so no swap window before the rename and no flushed candidate left behind when a reopen failed. - L3: a failed delete disposition is reported on stderr (code only). - L4: the DACL receipt reads the descriptor with GetNamedSecurityInfoW and asserts a protected DACL with exactly owner, SYSTEM and Administrators. - L5: a pre-existing staging name must fail as create_staging/80. Part of sisyphuslabs/omo-desktop-app#4199
code-yeongyu
force-pushed
the
feat/4199-native-no-replace-publish
branch
from
October 26, 2026 08:03
6af9812 to
02e44f8
Compare
… result
A failed FileDispositionInfo delete used to be one stderr line. publish_no_replace
now returns Publication { result, staging_left_behind }, and the N-API
publishNoReplace resolves { outcome, failure, stagingLeftBehind { path,
windowsError } } so the caller can remove the leftover file. OS failures resolve
as outcome "failed" (step and code) so the leftover survives them too; only an
unsupported platform throws. The bytes are never part of the result.
Review r1 LOW 3 (lead ruling). Part of sisyphuslabs/omo-desktop-app#4199.
The DACL receipt failed on the windows-latest runner (run 40301410410): its user is the built-in Administrator (RID 500), which ConvertSecurityDescriptorToString- SecurityDescriptorW prints as the alias LA, while the test expected the literal SID. The published DACL was correct (D:P(A;;FA;;;LA)(A;;FA;;;SY)(A;;FA;;;BA)). The expected owner ACE now goes through the same descriptor round trip, so a well-known SID compares as its alias and any other SID stays literal.
…eplace-publish # Conflicts: # crates/senpi-socket-secret/src/lib.rs
This branch has not been deployed
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.
Working...
Part of sisyphuslabs/omo-desktop-app#4199 (senpi PR S5, native half: the Windows primitive of design 4.3 and 4.5). Stacked on #4302; review only the top commit until #4302 merges, then this PR is retargeted to
main.Summary
crates/senpi-socket-secretgainspublish_no_replace(N-APIpublishNoReplace(stagingPath, finalPath, bytes)): first publication of a public socket secret on Windows without ever writing, copying onto or truncating the final name. No TypeScript caller yet; the TypeScript creation path that uses this primitive (andlink()on POSIX) is the next PR.Behaviour (design 4.3 steps 3-7, 4.5 Windows row)
CreateFileW(CREATE_NEW)in the caller's same directory, with aSECURITY_ATTRIBUTESwhose descriptor isD:P(A;;FA;;;<user SID>)(A;;FA;;;SY)(A;;FA;;;BA): a protected DACL (no inherited ACE) set before any byte is written; handle not inheritable.WriteFileuntil every byte is written (a zero-byte write is an error),FlushFileBuffers, close the writing handle.DELETE | SYNCHRONIZEandSetFileInformationByHandle(FileRenameInfo)withReplaceIfExists = FALSEand a full destination path.ERROR_ALREADY_EXISTS/ERROR_FILE_EXISTSis a collision: returnscollision, the caller reads and validates the winner. Any other failure returns the failed step and its Windows error; never a fallback.FileDispositionInfo), never by path; after a successful rename nothing is unlinked.Tests
Native receipts in
tests/native_publish.rs(Windows only;ci.ymlsocket-secret-native-windowsalready runscargo test -p senpi-socket-secret, and each prints aRECEIPT_PUBLISHline):published, 15collision, the final bytes equal the winner's candidate, no staging left (design test 2);icacls).RED: the primitive is new; its "can fail" proofs are the collision and race assertions, which a final-path
CREATE_ALWAYSwrite or aReplaceIfExists=TRUErename would fail.Gates
cargo fmt -p senpi-socket-secret -- --checkrc=0;cargo test -p senpi-socket-secret --lockedrc=0 on macOS (the Windows receipts compile out);cargo clippy -p senpi-socket-secret --locked --tests -- -D warningsrc=0 for bothx86_64-pc-windows-msvcandaarch64-pc-windows-msvc. The Windows run of the receipts is this PR's CI job.Not covered
Power-loss durability of the rename (design 4.5 separates it from atomic visibility) and UNC/SMB targets; this primitive is only used on local stores, which the locality classifier of #4302 decides.
Gates (exact head b75492c)
Gated push at this head:
bun run checkrc=0;cargo fmt -p senpi-socket-secret -- --checkrc=0;cargo test -p senpi-socket-secret --lockedrc=0;cargo clippy -p senpi-socket-secret --locked --tests --target x86_64-pc-windows-msvc -- -D warningsrc=0;node scripts/check-pr-changelog.mjs --base origin/feat/4199-windows-locality-adapter --labels no-changelogrc=0. Also run locally before the push: the same clippy onaarch64-pc-windows-msvcrc=0.Review fold r1 (review-4310-r1, FIX_FIRST -> head 91397f5)
CREATE_NEW, the owner-only DACL,GENERIC_WRITE | DELETEand share modeFILE_SHARE_READ. That handle writes the file, flushes it and renames it withFileRenameInfoandReplaceIfExists = FALSE. On any outcome exceptPublished(write, flush or rename error, or a collision), the same handle deletes the file throughFileDispositionInfo. Nothing is reopened or deleted by path (remove_stagingand the reopen are gone). So nothing can swap the file before the rename, and no flushed candidate is left behind on an error.FILE_SHARE_READlets readers of the final name in between the rename and this handle's close.Collision.GetNamedSecurityInfoWand converts it to SDDL. It asserts the protected flag and exactly three ACEs:A;;FA;;;<user SID from whoami /user>,A;;FA;;;SYandA;;FA;;;BA. No localized names are involved, andwhoamimust succeed.Os { step: "create_staging", code: 80 }.WriteFilelength now usesu32::try_from(...).unwrap_or(u32::MAX)and the loop continues.cargo fmt --checkpassed,cargo test -p senpi-socket-secret --lockedpassed 10, andcargo clippy --tests -D warningspassed for x86_64- and aarch64-pc-windows-msvc. That compiles the Windows tests, but there is no Windows host or VM, so the real-Windows receipts run only insocket-secret-native-windowsCI. Actions on this account was reported stalled at fold time.Review r1 LOW 3 fold (lead ruling, head 0afbce4)
A staging file left behind by a failed
FileDispositionInfodelete used to be one stderr line. It is now part of the result.publish_no_replacereturnsPublication { result, staging_left_behind: Option<u32> }; theu32is theGetLastErrorof the failed disposition. The stderr line is gone.publishNoReplaceresolves{ outcome: "published" | "collision" | "failed", failure?: { step, code }, stagingLeftBehind?: { path, windowsError } }. An OS failure now resolves asfailedinstead of throwing, so the leftover survives it too; only an unsupported platform throws. The bytes are never in the result.lib.rsunit tests did not compile on 02e44f8 (Publicationandpublish_resultdo not exist). A Windows-only unit test inpublish.rsinjects a failing disposition (|_| Err(5)) and assertsCollisionwithstaging_left_behind == Some(5), the staging file still present and the winner unchanged; it runs insocket-secret-native-windows. The existing receipts now also assert that no staging file was reported left behind.cargo fmt --check,cargo test -p senpi-socket-secret --locked(15 passed on Linux),cargo clippy --tests -D warningsfor x86_64- and aarch64-pc-windows-msvc,check-pr-changelog. The real-Windows run of the receipts is this head's CI job.publishSocketSecretNoReplace, typedstagingLeftBehindwith an action naming the path) is on build(native): ship the Windows socket-secret bridge with a loader that has no fallback #4312, where the loader lives.