Unix Domain Sockets Documentation & Example App#222
Merged
Conversation
… approach Rewrites integration tests to fork real child processes instead of using hand-rolled protocol clients, so echo prevention and transport registration are exercised exactly as they work in production. Also includes transport hardening fixes and regenerated API reference docs. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ink-based CLI tool for launching and monitoring multi-process postal scenarios with real-time event streaming via UDS transport. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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.
Unix Domain Sockets Documentation & Example App
Branch: unix-domain-sockets-deaux → unix-domain-socket
Changes: 3355 additions, 60 deletions across 55 files
Summary
This PR has 55 changed files but the bulk is generated docs and a lock file. The real work spans three commits.
e0b3285 — Harden UDS transport and replace integration tests with multi-process approach
The Mental Model Shift:
The UDS transport's handshake protocol now validates version numbers, not just message type strings. Previously,
isUdsSyn/isUdsAck/isUdsEnvelopeMessageaccepted anyversionfield value as long as the shape was correct — meaning a v2 client could silently handshake with a v1 server and get garbled envelopes. Now there's a strict version check, withlooksLikeSyn/looksLikeAckhelpers to distinguish "wrong version" from "not a postal message at all" — giving users an actionablePostalUdsVersionMismatchErrorinstead of a mysterious timeout.The integration test strategy also flipped entirely. Instead of hand-rolling protocol messages against mock sockets (which can't catch echo-prevention or transport-registration bugs), tests now fork real child processes via a CJS test helper (
uds-test-child.cjs). Each child gets its own postal instance, so the tests exercise the actual production flow: handshake, bidirectional pub/sub, fan-out, disconnect cleanup, filters, and version mismatch rejection.What Changed Structurally:
protocol.ts:isUdsSyn,isUdsAck,isUdsEnvelopeMessagenow requireversion === PROTOCOL_VERSION. NewlooksLikeSyn/looksLikeAckhelpers for loose matching.errors.ts: NewPostalUdsVersionMismatchErrorclass withreceivedandexpectedfields.client.ts: Version mismatch detection added before the ACK check — rejects fast with a clear error instead of timing out.server.ts: Version mismatch detection added before the SYN check — destroys the socket immediately.index.ts: ExportsPostalUdsVersionMismatchError.uds-test-child.cjs: New CJS child process helper that wraps the real postal + UDS APIs behind an IPC command interface.uds.integration.test.ts: ~500-line integration test suite using forked child processes. Covers: handshake, bidirectional messaging, fan-out, disconnect cleanup, server filter, onDisconnect callback, handshake timeout, concurrent connections (10 clients), and version mismatch rejection.protocol.test.ts,server.test.ts,serialization.test.ts,socketTransport.test.ts,client.test.ts: Version mismatch cases, duplicate SYN, filter pass-through, startup error,createLineParsercoverage, settled-before-connect guard.ee9f599 — Add postal-monitor example app
The Mental Model Shift:
This adds a real-world example app demonstrating
postal-transport-udsin action. It's an Ink-based TUI dashboard (monitor) that watches task events published by a launcher process over a Unix domain socket. The architecture is intentionally pedagogical —reporter.tsis three postal API calls and nothing else.What Changed Structurally:
examples/postal-monitor/package withpackage.json(@postal-examples/postal-monitor, private).reporter.ts: The pedagogical core —connectToSocket→getChannel→publish. Returns aReporterwithreportStarted/reportFinished/disconnect.task-runner.ts: Spawns pnpm commands viachild_process.spawn, reports start/finish via the reporter. Handles double-emit from Node's error+close pattern with asettledguard.launcher.ts: Entry point — resolves monorepo root, connects to the monitor socket, runs tasks with staggered random delays.monitor.tsx: UDS server entry point —listenOnSocket, subscribes totask.#, bridges postal events into React state via a mutablesetStateref, renders with Ink.monitor-state.ts: Pure state reducer (immutable updates) withcreateInitialState,applyTaskStarted,applyTaskFinished. Event log capped atMAX_EVENT_LOG_SIZE(50).App.tsx(two-column layout),ProcessList.tsx(tasks by PID),EventStream.tsx(scrolling log),format.ts(duration formatting).types.ts: Payload types +ChannelRegistrymodule augmentation for compile-time type safety on the "monitor" channel.monitor-state.test.ts(~408 lines, pure reducer tests),reporter.test.ts(~268 lines, mocked postal/UDS),launcher.test.ts(~373 lines, mocked spawn).72f9033 — Update docs for postal-monitor example and regenerate API references
What Changed Structurally:
astro.config.mjs: Addedpostal-monitorto the examples sidebar.Risk Callouts
New dependencies: The postal-monitor example adds
ink,chalk,react,@types/react,ink-testing-libraryas dependencies. These are scoped to a private example app, so no supply chain impact on consumers — but it's worth noting the React + Ink dependency tree for an example.astype assertions in monitor.tsx: Lines castenvelope.payloadtoTaskStartedPayload/TaskFinishedPayload. The comment explains why (ChannelRegistry augmentation not visible at runtime), and the reporter enforces the contract. Not a bug, but worth the reviewer's awareness — if the reporter shape drifts, the monitor would silently accept bad data.Mutable
setStateref pattern in monitor.tsx: The monitor bridges postal subscriptions into React state via a mutablesetStatereference. This is a known React pattern for bridging external event sources. The only risk is theif (!setState) returnguard — if an event arrives before the first render completes, it's silently dropped. Low risk for a demo.reporter.disconnect()is not idempotent: The test explicitly verifies that double-disconnect calls the underlying cleanup twice. Fine for a demo, but worth noting if this pattern gets copied into production code.Integration tests fork up to 12 child processes: The concurrent connections test spawns 10 clients + 1 server. This could be flaky on CI if the machine is resource-constrained.
Breaking behavioral change:
isUdsSyn/isUdsAck/isUdsEnvelopeMessagenow reject messages with wrong versions. If anyone was relying on cross-version handshakes, this will break. Pre-1.0 package on a feature branch, so low risk, but worth documenting in release notes.Tribal Knowledge Checks
General Checks
ascasts in monitor.tsx documented and intentional.no-explicit-anypragmas in tests standard for mocking.examples/postal-monitor(ink, chalk, react, etc.). Package is private — no downstream impact.isUdsSyn/isUdsAck/isUdsEnvelopeMessagenow reject wrong versions. NewPostalUdsVersionMismatchErrorexport.Unit Test Checks
export default {}: All new test files include it.Testing Recommendations
Manual Verification
start:monitorin one terminal,start:launcherin another.Automated Test Gaps
format.ts(formatDuration) has no dedicated unit tests — cheap to add.launcher.tsmonorepo root resolution andnode_modulescheck are untested (environment-dependent).Regression Risks
pnpm --filter postal-transport-uds testto confirm version-check hardening doesn't break existing tests.postal-monitorexample depends onworkspace:*links — if either package's API changes before merge, the example could break silently.