Platform

pragma-platform — the six OS seams and the rules that keep platform bugs out of call sites.

crates/pragma-platform owns every OS difference. The rule: a platform difference is a missing implementation that returns an error naming it — never a bare #[cfg(unix)] at a call site with a silently-empty #[cfg(not(unix))] twin. That pattern is how a security guarantee once quietly disappeared (a GitHub token written world-readable on Windows), and the crate exists so it cannot happen again.

The seams

ModuleUnixWindowsWhat it owns
ipcstd::os::unix::net (AF_UNIX)uds_windows (AF_UNIX, Win10 1803+)The local socket: bind with owner-restricted perms, connect, shutdown. Named pipes were rejected: they lack read timeouts and socket shutdown, which the wake-a-blocked-reader design depends on.
pathstd::fs::canonicalizesame, then strip the \\?\ verbatim prefixCanonical paths external programs accept; home_dir. Verbatim paths make git refuse to work and break prefix comparisons.
permschmod 0600 / 0700icacls /inheritance:r /grant:r <user>:(F)Owner-only files and directories; create_private_file restricts the empty file before contents exist.
processsysinfo, kill, pkillsysinfo, taskkill, tasklistKill, kill-tree, liveness (verified by process name), the process table, and windowless child spawning (CREATE_NO_WINDOW — a console child of a GUI process pops a console window without it).
shell$SHELL else platform defaultprobe pwsh.exe then powershell.exeWhich shell a PTY launches and its interactive args: PowerShell takes -NoLogo, never the POSIX -l; resolve_profile_launch maps a ShellProfile to a native launch or wsl.exe -d <distro>.
wslno distributions, everparse wsl.exe --list --verboseDistribution listing — lives here so a host answers the wsl RPC about itself (an SSH host must report its own distros).

The call-site rules these enable

  • Canonicalize with pragma_platform::path::canonicalize, never std::fs's.
  • Spawn with pragma_platform::process::command (or process_env::command, which wraps it), never a bare Command::new.
  • Name executables with pragma_client::executable_name — it appends EXE_SUFFIX, so pragma-cli becomes pragma-cli.exe on Windows. This applies to paths you write, not just ones you read.

Two rules that are not seams but bite the same way

  • A path is not a string. Compare with Path (/ and \ are equivalent separators on Windows), never assert on a "dir/file" suffix, and test absolutes with Path::is_absolutestarts_with('/') silently rejects every Windows form.
  • Clear the read timeout on a long-lived stream. configure_stream sets a 5 s timeout for request mode; leave it on an idle subscription and every quiet 5 s looks like a drop, so the client warns and reconnects forever. Call set_read_timeout(None) once the response arrives (open_event_stream does exactly this).

On this page