socketduct 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +11 -0
- package/.env.example +131 -0
- package/AGENTS.md +168 -0
- package/Dockerfile +30 -0
- package/README.md +134 -0
- package/changelog.d/20260716083144-v2-ack-wire-format.md +3 -0
- package/changelog.d/20260716092044-v2-only-stream-framing.md +1 -0
- package/changelog.d/20260727113000-relay-connect-timeout-destroy.md +1 -0
- package/changelog.d/20260813093000-private-relay-hardening.md +1 -0
- package/changelog.d/20260824183412-initial-target-recovery-https.md +1 -0
- package/changelog.d/20260824230000-tls-relay-session-close.md +1 -0
- package/changelog.d/20260825120000-reconnect-close-target-timeout.md +1 -0
- package/changelog.d/20260829120000-protocol-v3-multiplexing.md +1 -0
- package/changelog.d/20260829160000-v3-review-corrections.md +1 -0
- package/changelog.d/20260830000000-fix-socket-idle-timeout.md +1 -0
- package/changelog.d/20260830090000-multi-gateway-transport-set.md +1 -0
- package/changelog.d/20260830093000-relay-close-settlement.md +1 -0
- package/changelog.d/20260830120000-immutable-gateway-image.md +1 -0
- package/changelog.d/20260902210000-native-reverse-gateway.md +1 -0
- package/changelog.d/20260902230000-relay-resume-terminal-order.md +1 -0
- package/changelog.d/20260902230708-multiplexed-open-ownership.md +1 -0
- package/changelog.d/20260902231541-multiplexed-terminal-close.md +1 -0
- package/changelog.d/20260902231542-reverse-close-position.md +1 -0
- package/changelog.d/20260902231543-reverse-terminal-connect.md +1 -0
- package/changelog.d/20260902233000-reverse-gateway-bounds.md +1 -0
- package/changelog.d/20260903001000-reverse-data-ordering.md +1 -0
- package/changelog.d/20260903003000-reverse-hub-restart-window.md +1 -0
- package/changelog.d/20260903010000-reverse-terminal-lifecycle.md +1 -0
- package/changelog.d/20260904142743-transport-set-readiness-wait.md +1 -0
- package/changelog.d/20260904152855-deferred-open-snapshots-binary-views.md +1 -0
- package/changelog.d/20260904163041-tensorbuzz-container-workflow.md +1 -0
- package/changelog.d/20260904174955-transport-set-terminal-causes.md +1 -0
- package/changelog.d/20260905081000-contain-reverse-auth-write-errors.md +1 -0
- package/changelog.d/20260905100520-reverse-hub-close-race.md +1 -0
- package/changelog.d/20260905120000-persistent-jsonl-logging.md +1 -0
- package/changelog.d/20260908071009-jsonl-partial-append-recovery.md +1 -0
- package/changelog.d/20260908074916-private-log-directory-setup.md +1 -0
- package/changelog.d/20260909093057-reverse-large-write-backpressure.md +1 -0
- package/changelog.d/20260909135830-actionable-error-diagnostics.md +1 -0
- package/changelog.d/20260909150000-transport-set-error-redaction.md +1 -0
- package/docker-compose.dev.yml +19 -0
- package/docker-compose.reverse-gateway.yml +36 -0
- package/docker-compose.yml +73 -0
- package/docs/architecture.md +264 -0
- package/docs/docker-topology.md +164 -0
- package/docs/docker.md +281 -0
- package/docs/logging.md +185 -0
- package/docs/plans/initial-implementation.md +205 -0
- package/docs/plans/socket-docker-integration.md +221 -0
- package/docs/protocol.md +558 -0
- package/docs/releasing.md +18 -0
- package/docs/reverse-gateway.md +186 -0
- package/docs/runbooks/jsonl-integrity-rollout.md +144 -0
- package/docs/running.md +215 -0
- package/docs/security.md +258 -0
- package/docs/session-lifecycle.md +127 -0
- package/docs/socket-api.md +448 -0
- package/eslint.config.js +36 -0
- package/package.json +44 -0
- package/scripts/deploy-gateway.js +194 -0
- package/scripts/test.js +28 -0
- package/src/auth/passwords.js +38 -0
- package/src/auth/static-token-store.js +41 -0
- package/src/auth/user-store.js +139 -0
- package/src/client/connect.js +76 -0
- package/src/client/deferred-virtual-socket.js +312 -0
- package/src/client/http-agent.js +101 -0
- package/src/client/https-agent.js +366 -0
- package/src/client/multiplexed-connection.js +1504 -0
- package/src/client/multiplexed-transport-set.js +917 -0
- package/src/client/multiplexed.js +3 -0
- package/src/client/socketduct-socket.js +1174 -0
- package/src/client/virtual-socket.js +256 -0
- package/src/config/environment.js +400 -0
- package/src/edge/tcp-edge.js +82 -0
- package/src/index.js +101 -0
- package/src/logging/structured-logger.js +745 -0
- package/src/protocol/compression.js +325 -0
- package/src/protocol/frame.js +341 -0
- package/src/protocol/v3-compression.js +44 -0
- package/src/protocol/v3-frame.js +209 -0
- package/src/proxy/multiplexed-relay.js +798 -0
- package/src/proxy/tcp-relay.js +1191 -0
- package/src/relay.js +3 -0
- package/src/reverse/client.js +721 -0
- package/src/reverse/common.js +88 -0
- package/src/reverse/gateway.js +663 -0
- package/src/reverse/hub.js +563 -0
- package/src/reverse/index.js +3 -0
- package/src/reverse/runtime.js +78 -0
- package/src/server/control-handler.js +170 -0
- package/src/server/primary.js +64 -0
- package/src/server/relay-runtime.js +124 -0
- package/src/server/worker.js +39 -0
- package/src/sessions/session.js +212 -0
- package/src/spool/spool-file.js +451 -0
- package/tensorbuzz.yml +36 -0
- package/test/e2e/gateway-process.test.js +262 -0
- package/test/e2e/reverse-gateway-process.test.js +285 -0
- package/test/fixtures/logging/enospc-matrix.mjs +238 -0
- package/test/fixtures/logging/enospc-recovery.mjs +146 -0
- package/test/fixtures/logging/process-writer.mjs +20 -0
- package/test/helpers/tls-certificates.js +115 -0
- package/test/integration/initial-target-recovery.test.js +518 -0
- package/test/integration/logging-recovery.test.js +163 -0
- package/test/integration/multiplexed-compatibility.test.js +254 -0
- package/test/integration/multiplexed-corrections.test.js +551 -0
- package/test/integration/multiplexed-failures.test.js +339 -0
- package/test/integration/multiplexed-transport-set.test.js +456 -0
- package/test/integration/multiplexed-transport.test.js +208 -0
- package/test/integration/reverse-gateway.test.js +1293 -0
- package/test/integration/socketduct-http-agent.test.js +435 -0
- package/test/integration/socketduct-https-agent.test.js +669 -0
- package/test/integration/stream-compression.test.js +1267 -0
- package/test/integration/tcp-forwarding.test.js +2878 -0
- package/test/integration/tls-forwarding.test.js +748 -0
- package/test/unit/auth/auth.test.js +64 -0
- package/test/unit/auth/static-token-store.test.js +14 -0
- package/test/unit/client/connect.test.js +58 -0
- package/test/unit/client/multiplexed-spool-budget.test.js +309 -0
- package/test/unit/client/multiplexed-transport-set.test.js +906 -0
- package/test/unit/client/socketduct-socket.test.js +1124 -0
- package/test/unit/client/virtual-socket.test.js +98 -0
- package/test/unit/config/docker-gateway-files.test.js +274 -0
- package/test/unit/config/environment.test.js +507 -0
- package/test/unit/index.test.js +78 -0
- package/test/unit/logging/structured-logger.test.js +674 -0
- package/test/unit/protocol/compression.test.js +421 -0
- package/test/unit/protocol/frame.test.js +336 -0
- package/test/unit/protocol/v3-compression.test.js +31 -0
- package/test/unit/protocol/v3-frame.test.js +57 -0
- package/test/unit/release-configuration.test.js +21 -0
- package/test/unit/server/control-handler.test.js +291 -0
- package/test/unit/server/primary.test.js +59 -0
- package/test/unit/server/relay-runtime.test.js +434 -0
- package/test/unit/sessions/session.test.js +84 -0
- package/test/unit/spool/spool-file.test.js +295 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# Socket API and Docker Topology Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task.
|
|
4
|
+
|
|
5
|
+
**Goal:** Add a Node socket-compatible Socketduct client API and carry it through docker-quack into TensorBuzz's Docker server workflow.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Extract the existing per-connection logic from `startTcpEdge()` into a reusable `Duplex`-compatible client socket, layer a connection factory and HTTP agent on top, then adapt docker-quack and TensorBuzz to opt into that transport per Docker server. Keep relay target authorization deny-by-default and keep direct Docker fallback available during rollout.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js ES modules, normal JavaScript with JSDoc, Node `Duplex`/`http.Agent`, built-in `node:test`, existing Socketduct framed TCP protocol, docker-quack, TensorBuzz.
|
|
10
|
+
|
|
11
|
+
## Cross-repository scope
|
|
12
|
+
|
|
13
|
+
Tasks 1-6 happen in this Socketduct repository. Tasks 7-9 happen in `/opt/data/projects/docker-quack`. Tasks 10-13 happen in `/opt/data/projects/tensorbuzz` with local Socketduct and docker-quack checkouts used by the smoke harness.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Task 1: Implement `SocketductSocket` skeleton
|
|
18
|
+
|
|
19
|
+
**Objective:** Create a socket-shaped `Duplex` that owns one Socketduct relay session.
|
|
20
|
+
|
|
21
|
+
**Files:**
|
|
22
|
+
- Create: `src/client/socketduct-socket.js`
|
|
23
|
+
- Create: `test/unit/client/socketduct-socket.test.js`
|
|
24
|
+
- Modify: `package.json` exports if needed
|
|
25
|
+
|
|
26
|
+
**Steps:**
|
|
27
|
+
1. Write tests asserting the object is a `Duplex`, exposes common socket methods/properties, has a public `.connect()` method that returns `this`, and no-op compatibility methods return `this`.
|
|
28
|
+
2. Implement constructor state, `.connect()`, `setTimeout`, `setNoDelay`, `setKeepAlive`, `address`, `ref`, `unref`, `_read`, `_write`, `_final`, and `_destroy` skeletons.
|
|
29
|
+
3. Verify with `node --test test/unit/client/socketduct-socket.test.js`, `npm run lint`, `npm run typecheck`.
|
|
30
|
+
|
|
31
|
+
**Commit:** `feat: add Socketduct socket client skeleton`
|
|
32
|
+
|
|
33
|
+
## Task 2: Move edge connection protocol into `SocketductSocket`
|
|
34
|
+
|
|
35
|
+
**Objective:** Make `SocketductSocket` create/resume sessions and stream bytes without a local TCP listener.
|
|
36
|
+
|
|
37
|
+
**Files:**
|
|
38
|
+
- Modify: `src/client/socketduct-socket.js`
|
|
39
|
+
- Modify: `src/edge/tcp-edge.js`
|
|
40
|
+
- Create/modify: `test/integration/socketduct-socket-forwarding.test.js`
|
|
41
|
+
|
|
42
|
+
**Steps:**
|
|
43
|
+
1. Write integration test using fake target + `startTcpRelay()` + `SocketductSocket` directly.
|
|
44
|
+
2. Port session create/resume, frame handling, spooling, sequence, ack, and reconnect logic from `EdgeConnection`.
|
|
45
|
+
3. Refactor `startTcpEdge()` to create a `SocketductSocket` per app socket and pipe both directions.
|
|
46
|
+
4. Verify existing edge integration tests still pass.
|
|
47
|
+
|
|
48
|
+
**Commit:** `feat: route edge traffic through SocketductSocket`
|
|
49
|
+
|
|
50
|
+
## Task 3: Add `connectSocketduct()` and connection factory
|
|
51
|
+
|
|
52
|
+
**Objective:** Provide ergonomic public APIs that mirror `net.connect()` and `createConnection` hooks.
|
|
53
|
+
|
|
54
|
+
**Files:**
|
|
55
|
+
- Create: `src/client/connect.js`
|
|
56
|
+
- Modify: package exports / `src/index.js` as appropriate
|
|
57
|
+
- Create: `test/unit/client/connect.test.js`
|
|
58
|
+
|
|
59
|
+
**Steps:**
|
|
60
|
+
1. Test `connectSocketduct(options)` returns a `SocketductSocket` immediately and calls `.connect()` asynchronously.
|
|
61
|
+
2. Test `createSocketductConnectionFactory(baseOptions)` merges per-call target/session options.
|
|
62
|
+
3. Document that relay token is required and never logged.
|
|
63
|
+
|
|
64
|
+
**Commit:** `feat: add Socketduct connection factory`
|
|
65
|
+
|
|
66
|
+
## Task 4: Add `SocketductHttpAgent`
|
|
67
|
+
|
|
68
|
+
**Objective:** Let Node HTTP clients route requests over Socketduct sockets.
|
|
69
|
+
|
|
70
|
+
**Files:**
|
|
71
|
+
- Create: `src/client/http-agent.js`
|
|
72
|
+
- Create: `test/integration/socketduct-http-agent.test.js`
|
|
73
|
+
|
|
74
|
+
**Steps:**
|
|
75
|
+
1. Test `http.request({agent})` can call a fake Docker-style `/_ping` endpoint through relay.
|
|
76
|
+
2. Test keep-alive reuses a live Socketduct socket when the HTTP agent keeps it open.
|
|
77
|
+
3. Test unauthorized targets fail as HTTP connection errors.
|
|
78
|
+
4. Verify with full test suite.
|
|
79
|
+
|
|
80
|
+
**Commit:** `feat: add HTTP agent for Socketduct sockets`
|
|
81
|
+
|
|
82
|
+
## Task 5: Harden socket reconnection semantics
|
|
83
|
+
|
|
84
|
+
**Objective:** Make reconnect behavior predictable for socket-style consumers.
|
|
85
|
+
|
|
86
|
+
**Files:**
|
|
87
|
+
- Modify: `src/client/socketduct-socket.js`
|
|
88
|
+
- Modify/create: reconnect tests under `test/integration/`
|
|
89
|
+
- Modify docs: `docs/socket-api.md`, `docs/session-lifecycle.md`
|
|
90
|
+
|
|
91
|
+
**Steps:**
|
|
92
|
+
1. Add tests for relay tunnel drop with target retained and socket staying open.
|
|
93
|
+
2. Add tests for resume expiry causing `error` then `close`.
|
|
94
|
+
3. Add max interrupted duration and spool size guards.
|
|
95
|
+
4. Add backpressure-focused tests for large writes.
|
|
96
|
+
|
|
97
|
+
**Commit:** `feat: harden Socketduct socket reconnect behavior`
|
|
98
|
+
|
|
99
|
+
## Task 6: Add Docker-host gateway container mode
|
|
100
|
+
|
|
101
|
+
**Objective:** Support a documented server-local Socketduct relay container for Docker servers.
|
|
102
|
+
|
|
103
|
+
**Files:**
|
|
104
|
+
- Modify: `docker-compose.yml`, `.env.example`, `docs/docker.md`
|
|
105
|
+
- Create optional docs/scripts for Docker socket shim if chosen
|
|
106
|
+
- Add runtime config tests if env shape changes
|
|
107
|
+
|
|
108
|
+
**Steps:**
|
|
109
|
+
1. Add Compose example for Docker target allowlist.
|
|
110
|
+
2. Document TCP target, private shim target, and host-network target options.
|
|
111
|
+
3. Ensure placeholders remain rejected and secrets remain ignored.
|
|
112
|
+
4. Validate with process-level tests when Docker is unavailable.
|
|
113
|
+
|
|
114
|
+
**Commit:** `feat: document Docker server gateway mode`
|
|
115
|
+
|
|
116
|
+
## Task 7: Add docker-quack transport abstraction
|
|
117
|
+
|
|
118
|
+
**Objective:** Let docker-quack use custom agents/socket factories without knowing about TensorBuzz.
|
|
119
|
+
|
|
120
|
+
**Files:**
|
|
121
|
+
- In `docker-quack`: modify `src/docker-connection.js` and exports
|
|
122
|
+
- Add tests under `spec/`
|
|
123
|
+
|
|
124
|
+
**Steps:**
|
|
125
|
+
1. Add `agent` and/or `createConnection` options to `DockerConnection`.
|
|
126
|
+
2. Pass the transport to SnapReq/HTTP plumbing or adapt SnapReq if needed.
|
|
127
|
+
3. Test buffered requests against a fake HTTP server using a custom transport.
|
|
128
|
+
|
|
129
|
+
**Commit:** `feat: support custom Docker transports`
|
|
130
|
+
|
|
131
|
+
## Task 8: Wire docker-quack to Socketduct transport
|
|
132
|
+
|
|
133
|
+
**Objective:** Provide a docker-quack helper or documented integration that builds a Socketduct-backed Docker connection.
|
|
134
|
+
|
|
135
|
+
**Files:**
|
|
136
|
+
- In `docker-quack`: add helper module or docs
|
|
137
|
+
- Add integration tests with local Socketduct relay and fake Docker API
|
|
138
|
+
|
|
139
|
+
**Steps:**
|
|
140
|
+
1. Use `SocketductHttpAgent` or `createSocketductConnectionFactory` as docker-quack transport.
|
|
141
|
+
2. Test `/_ping` and `/version` over Socketduct.
|
|
142
|
+
3. Keep Socketduct optional so docker-quack still works standalone.
|
|
143
|
+
|
|
144
|
+
**Commit:** `feat: add Socketduct Docker transport support`
|
|
145
|
+
|
|
146
|
+
## Task 9: Add Docker streaming and hijack conformance tests
|
|
147
|
+
|
|
148
|
+
**Objective:** Prove Docker streaming endpoints survive the Socketduct transport layer.
|
|
149
|
+
|
|
150
|
+
**Files:**
|
|
151
|
+
- In `docker-quack`: streaming/hijack tests
|
|
152
|
+
- In `socketduct`: HTTP agent upgrade/stream tests if missing
|
|
153
|
+
|
|
154
|
+
**Steps:**
|
|
155
|
+
1. Test chunked logs/events-style streaming.
|
|
156
|
+
2. Test upgraded bidirectional attach/exec-style stream against a fake daemon.
|
|
157
|
+
3. Verify no buffering layer consumes the stream prematurely.
|
|
158
|
+
|
|
159
|
+
**Commit:** `test: cover Docker streaming over Socketduct`
|
|
160
|
+
|
|
161
|
+
## Task 10: Add TensorBuzz Socketduct configuration model
|
|
162
|
+
|
|
163
|
+
**Objective:** Let each Docker server choose direct or Socketduct Docker transport.
|
|
164
|
+
|
|
165
|
+
**Files:**
|
|
166
|
+
- In `tensorbuzz`: Docker server model/config files
|
|
167
|
+
- Tests for validation and redaction
|
|
168
|
+
|
|
169
|
+
**Steps:**
|
|
170
|
+
1. Add rollout mode fields and secret references.
|
|
171
|
+
2. Validate target host/port and relay host/port.
|
|
172
|
+
3. Redact tokens/secrets in serializers, logs, and errors.
|
|
173
|
+
|
|
174
|
+
**Commit:** `feat: add Socketduct Docker server configuration`
|
|
175
|
+
|
|
176
|
+
## Task 11: Add TensorBuzz gateway lifecycle/provisioning
|
|
177
|
+
|
|
178
|
+
**Objective:** Provision or document the Docker-server-local Socketduct gateway container.
|
|
179
|
+
|
|
180
|
+
**Files:**
|
|
181
|
+
- In `tensorbuzz`: services/scripts/admin flows touching Docker server setup
|
|
182
|
+
- Tests for generated Compose/env config without real secrets
|
|
183
|
+
|
|
184
|
+
**Steps:**
|
|
185
|
+
1. Generate or document server-local gateway settings.
|
|
186
|
+
2. Add safe lifecycle commands/status probes.
|
|
187
|
+
3. Keep final destructive operations confirmation-gated where UI/admin flows require it.
|
|
188
|
+
|
|
189
|
+
**Commit:** `feat: add Socketduct gateway lifecycle support`
|
|
190
|
+
|
|
191
|
+
## Task 12: Add TensorBuzz observability and fallback behavior
|
|
192
|
+
|
|
193
|
+
**Objective:** Make rollout safe and debuggable.
|
|
194
|
+
|
|
195
|
+
**Files:**
|
|
196
|
+
- In `tensorbuzz`: build container handler / Docker connection factory / logging
|
|
197
|
+
- Tests for direct, shadow, preferred, and required modes
|
|
198
|
+
|
|
199
|
+
**Steps:**
|
|
200
|
+
1. Add direct fallback for safe operations in `preferred` mode.
|
|
201
|
+
2. Add health probes and structured telemetry fields.
|
|
202
|
+
3. Ensure logs never include tokens or raw Docker payloads.
|
|
203
|
+
|
|
204
|
+
**Commit:** `feat: add Socketduct Docker rollout controls`
|
|
205
|
+
|
|
206
|
+
## Task 13: Add cross-repo e2e smoke test
|
|
207
|
+
|
|
208
|
+
**Objective:** Prove TensorBuzz + docker-quack + Socketduct work together against a fake Docker daemon.
|
|
209
|
+
|
|
210
|
+
**Files:**
|
|
211
|
+
- In `tensorbuzz` or CI scripts: cross-repo smoke harness
|
|
212
|
+
- Docs describing how to run locally
|
|
213
|
+
|
|
214
|
+
**Steps:**
|
|
215
|
+
1. Start fake Docker API server.
|
|
216
|
+
2. Start Socketduct relay with target allowlist to the fake daemon.
|
|
217
|
+
3. Configure docker-quack through Socketduct.
|
|
218
|
+
4. Run TensorBuzz build-server probe path.
|
|
219
|
+
5. Verify green CI and document local Docker limitations.
|
|
220
|
+
|
|
221
|
+
**Commit:** `test: add Socketduct Docker cross-repo smoke coverage`
|