Title: feat(local_socket): Unix core — Listen/Dial, runtime dir resolution, secure cleanup
Context
First phase of interprocess-go, a Go counterpart to the Rust interprocess crate providing
local connection-oriented byte streams over a unified API. Design is D5 (Implementable):
four-file-cloud/docs/interprocess-go-concept.md.
Scope of this issue: Linux and macOS only. No Windows code, no framing subpackage — those are
Phases 2 and 4.
Deliverables
local_socket package: Name, NameKind, Filesystem(), Namespaced(), UserScoped(),
Listen(), Dial(), ListenOptions, DialOptions, AccessPolicy, PeerIdentity
- Returns
net.Listener / net.Conn; the Listener and Conn interfaces add
LocalSocketName() and PeerIdentity()
- Error sentinels:
ErrInvalidName, ErrUnsupportedName, ErrPermissionDenied,
ErrAlreadyInUse, ErrStaleCleanupUnsafe, ErrNoRuntimeDir, ErrPeerIdentityUnsupported
examples/echo
- CI:
ubuntu-latest, macos-latest, -race
Acceptance criteria
Concept §Implementation Phases, Phase 1 — criteria 1.1 through 1.14. All must pass.
Load-bearing ones, called out because they are easy to get subtly wrong:
- 1.3 every runtime-dir candidate is validated for owner and mode, whatever its source.
Test: set $TMPDIR to a 0777 dir on Linux and assert it is skipped. $TMPDIR is a Darwin-only
precedence step (Decision 2) — on Linux it conventionally means world-writable /tmp.
- 1.6 stale reclaim removes only an owned socket. Test: place a regular file at the socket
path, assert ErrStaleCleanupUnsafe.
- 1.8
Close() unblocks Accept() with an error satisfying errors.Is(err, net.ErrClosed).
- 1.9 dial cancellation leaks no goroutine.
- 1.10
PeerIdentity() returns correct UID/GID — SO_PEERCRED (Linux), getpeereid (macOS).
Explicitly out of scope
Windows/named pipes (Phase 2) · Rust interop (Phase 3) · framing (Phase 4) · Linux abstract
namespace (Decision 3, declined permanently) · unnamed_pipe, fifo_file, message-mode pipes
(Tier 4, not ported)
Definition of done
- All 14 criteria pass, CI green on both platforms with
-race
go vet and the project linter clean
- No dependency beyond the standard library in this phase
Title: feat(local_socket): Unix core — Listen/Dial, runtime dir resolution, secure cleanup
Context
First phase of
interprocess-go, a Go counterpart to the Rustinterprocesscrate providinglocal connection-oriented byte streams over a unified API. Design is D5 (Implementable):
four-file-cloud/docs/interprocess-go-concept.md.Scope of this issue: Linux and macOS only. No Windows code, no framing subpackage — those are
Phases 2 and 4.
Deliverables
local_socketpackage:Name,NameKind,Filesystem(),Namespaced(),UserScoped(),Listen(),Dial(),ListenOptions,DialOptions,AccessPolicy,PeerIdentitynet.Listener/net.Conn; theListenerandConninterfaces addLocalSocketName()andPeerIdentity()ErrInvalidName,ErrUnsupportedName,ErrPermissionDenied,ErrAlreadyInUse,ErrStaleCleanupUnsafe,ErrNoRuntimeDir,ErrPeerIdentityUnsupportedexamples/echoubuntu-latest,macos-latest,-raceAcceptance criteria
Concept §Implementation Phases, Phase 1 — criteria 1.1 through 1.14. All must pass.
Load-bearing ones, called out because they are easy to get subtly wrong:
Test: set
$TMPDIRto a0777dir on Linux and assert it is skipped.$TMPDIRis a Darwin-onlyprecedence step (Decision 2) — on Linux it conventionally means world-writable
/tmp.path, assert
ErrStaleCleanupUnsafe.Close()unblocksAccept()with an error satisfyingerrors.Is(err, net.ErrClosed).PeerIdentity()returns correct UID/GID —SO_PEERCRED(Linux),getpeereid(macOS).Explicitly out of scope
Windows/named pipes (Phase 2) · Rust interop (Phase 3) ·
framing(Phase 4) · Linux abstractnamespace (Decision 3, declined permanently) ·
unnamed_pipe,fifo_file, message-mode pipes(Tier 4, not ported)
Definition of done
-racego vetand the project linter clean