Skip to content

feat(local_socket): Unix core — Listen/Dial, runtime dir resolution, secure cleanup - #6

Open
four-bytes-robby wants to merge 5 commits into
mainfrom
feat/GH-1-unix-core
Open

feat(local_socket): Unix core — Listen/Dial, runtime dir resolution, secure cleanup#6
four-bytes-robby wants to merge 5 commits into
mainfrom
feat/GH-1-unix-core

Conversation

@four-bytes-robby

Copy link
Copy Markdown
Member

Closes #1

Phase 1 of interprocess-go: the local_socket package on Linux and macOS. 1380 lines, 28 tests, no skips.

Acceptance criteria

All 14 from docs/TESTING.md Phase 1 pass, except 1.14 which is partial — see below.

The five load-bearing ones each have a named test:

# Test
1.3 runtime dir validation TestValidateRuntimeDir, TestExplicitRuntimeDirValidated, TestTMPDIRIgnoredOnLinux
1.4 ErrNoRuntimeDir TestNoValidCandidateReturnsErrNoRuntimeDir (two subtests)
1.6 stale cleanup TestStaleCleanupRefusesRegularFile, TestStaleCleanupRefusesSymlink
1.8 Close unblocks Accept TestCloseUnblocksAccept
1.10 peer identity TestPeerIdentity

Three defects found and fixed during review

RemoveOnClose was opt-in. ListenCloseListen returned ErrAlreadyInUse unless the caller set two options, so no service could restart on default settings. Replaced by KeepOnClose with inverted meaning, so the zero value releases the socket. ReclaimStale stays opt-in on purpose — remove what this process created, never touch what it did not.

Criterion 1.4 was never exercised. The test skipped itself whenever /run/user/$UID existed, which is every systemd host. The candidate chain is now injectable and covers an empty set, a set where every candidate fails validation, and the assertion that nothing is written into a rejected directory.

The macOS build never compiled. peer_darwin.go called syscall.Getpeereid, which exists in no Go standard library on any platform. Replaced with unix.GetsockoptXucred(fd, SOL_LOCAL, LOCAL_PEERCRED). Cross-compilation is now part of the documented local gate — it needs no hardware and catches this whole class.

Known gap

  • macOS runtime verification — no macOS hardware available. darwin/arm64 and darwin/amd64 cross-compile and vet cleanly; peerCred, the Darwin $TMPDIR precedence step and APFS mode enforcement have never executed. Stated in README, ROADMAP and CONTRIBUTE rather than implied as covered.

Local gate

gofmt -l .                         # empty
go vet ./...                       # clean
go test -race ./...                # ok, 28 tests, 0 skips
GOOS=darwin GOARCH=arm64 go build  # ok
GOOS=darwin GOARCH=amd64 go build  # ok

Adds golang.org/x/sys as the single dependency, and raises the minimum to Go 1.25 (x/sys v0.47.0 declares go 1.25.0).

four-bytes-robby and others added 5 commits August 29, 2026 18:45
…oRuntimeDir (#1)

RemoveOnClose replaced by KeepOnClose with inverted meaning. The opt-in
default meant Listen -> Close -> Listen returned ErrAlreadyInUse unless
the caller set two options, so no service could restart on default
settings. It also diverged from Go, whose UnixListener unlinks a socket
it created, and from Rust interprocess, where name release is part of
local-socket semantics.

ReclaimStale stays opt-in. The rule is asymmetric on purpose: remove what
this process created, never touch what it did not.

Criterion 1.4 was never exercised - the test skipped itself whenever
/run/user/$UID existed, which is every systemd host. The candidate chain
is now injectable, and the test covers an empty set, a set where every
candidate fails validation, and the assertion that nothing is written
into a rejected directory.

- KeepOnClose replaces RemoveOnClose; SetUnlinkOnClose(!KeepOnClose)
- TestCloseRemovesSocketByDefault asserts restart with zero options
- TestKeepOnCloseLeavesSocket covers the opt-out and its ErrAlreadyInUse
- docs/ARCHITECTURE.md, docs/TESTING.md, HISTORY.md updated
- 28 tests, no skips, gofmt/vet clean, -race green on Linux
… gate (#1)

peer_darwin.go called syscall.Getpeereid, which exists in no Go standard
library on any platform. The darwin build never compiled - a fact
provable from Linux in one second, and missed because nothing
cross-compiled.

Replaced with the actual macOS primitive:
GetsockoptXucred(fd, SOL_LOCAL, LOCAL_PEERCRED) from golang.org/x/sys.
struct xucred carries a UID and a group list but no PID, so
PeerIdentity.PID stays zero on Darwin, as already documented.

This adds golang.org/x/sys as the package's single dependency. The
'standard library only' constraint in issue #1 does not survive contact
with a platform primitive the standard library does not expose, and
x/sys is the canonical source maintained by the Go team.

Cross-compilation is now part of the documented local gate. It needs no
hardware, costs a second, and catches the entire class. Compiling is not
testing - but a platform file that does not compile is not a testing
gap, it is a broken build.

- CONTRIBUTE.md, AGENTS.md: GOOS=darwin/windows build in the gate
- docs/TESTING.md: criterion 1.14 restated honestly
- HISTORY.md: the defect and its cause recorded
golang.org/x/sys v0.47.0 declares 'go 1.25.0', so a 1.24 toolchain
cannot build this module. Declaring 1.24 while depending on it was a
floor the project could not honour - it happened to build here only
because the local toolchain is newer.

go.mod, AGENTS.md, GUIDELINES.md and HISTORY.md now agree on 1.25.
The maintainer has no macOS hardware, so the darwin path cross-compiles
and vets cleanly but has never executed. Rather than let the platform
table imply coverage, name exactly what is unverified: peerCred via
getsockopt(SOL_LOCAL, LOCAL_PEERCRED), the Darwin-only $TMPDIR
precedence step, and mode enforcement on APFS.

A green cross-compile proves the code exists and type-checks, not that
it behaves.

- README: verification column plus a section on the gap
- ROADMAP: Linux checked, macOS runtime listed as blocked
- CONTRIBUTE: where a platform cannot be run, say so in the PR
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.

feat(local_socket): Unix core — Listen/Dial, runtime dir resolution, secure cleanup

2 participants