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.
Files changed (138) hide show
  1. package/.dockerignore +11 -0
  2. package/.env.example +131 -0
  3. package/AGENTS.md +168 -0
  4. package/Dockerfile +30 -0
  5. package/README.md +134 -0
  6. package/changelog.d/20260716083144-v2-ack-wire-format.md +3 -0
  7. package/changelog.d/20260716092044-v2-only-stream-framing.md +1 -0
  8. package/changelog.d/20260727113000-relay-connect-timeout-destroy.md +1 -0
  9. package/changelog.d/20260813093000-private-relay-hardening.md +1 -0
  10. package/changelog.d/20260824183412-initial-target-recovery-https.md +1 -0
  11. package/changelog.d/20260824230000-tls-relay-session-close.md +1 -0
  12. package/changelog.d/20260825120000-reconnect-close-target-timeout.md +1 -0
  13. package/changelog.d/20260829120000-protocol-v3-multiplexing.md +1 -0
  14. package/changelog.d/20260829160000-v3-review-corrections.md +1 -0
  15. package/changelog.d/20260830000000-fix-socket-idle-timeout.md +1 -0
  16. package/changelog.d/20260830090000-multi-gateway-transport-set.md +1 -0
  17. package/changelog.d/20260830093000-relay-close-settlement.md +1 -0
  18. package/changelog.d/20260830120000-immutable-gateway-image.md +1 -0
  19. package/changelog.d/20260902210000-native-reverse-gateway.md +1 -0
  20. package/changelog.d/20260902230000-relay-resume-terminal-order.md +1 -0
  21. package/changelog.d/20260902230708-multiplexed-open-ownership.md +1 -0
  22. package/changelog.d/20260902231541-multiplexed-terminal-close.md +1 -0
  23. package/changelog.d/20260902231542-reverse-close-position.md +1 -0
  24. package/changelog.d/20260902231543-reverse-terminal-connect.md +1 -0
  25. package/changelog.d/20260902233000-reverse-gateway-bounds.md +1 -0
  26. package/changelog.d/20260903001000-reverse-data-ordering.md +1 -0
  27. package/changelog.d/20260903003000-reverse-hub-restart-window.md +1 -0
  28. package/changelog.d/20260903010000-reverse-terminal-lifecycle.md +1 -0
  29. package/changelog.d/20260904142743-transport-set-readiness-wait.md +1 -0
  30. package/changelog.d/20260904152855-deferred-open-snapshots-binary-views.md +1 -0
  31. package/changelog.d/20260904163041-tensorbuzz-container-workflow.md +1 -0
  32. package/changelog.d/20260904174955-transport-set-terminal-causes.md +1 -0
  33. package/changelog.d/20260905081000-contain-reverse-auth-write-errors.md +1 -0
  34. package/changelog.d/20260905100520-reverse-hub-close-race.md +1 -0
  35. package/changelog.d/20260905120000-persistent-jsonl-logging.md +1 -0
  36. package/changelog.d/20260908071009-jsonl-partial-append-recovery.md +1 -0
  37. package/changelog.d/20260908074916-private-log-directory-setup.md +1 -0
  38. package/changelog.d/20260909093057-reverse-large-write-backpressure.md +1 -0
  39. package/changelog.d/20260909135830-actionable-error-diagnostics.md +1 -0
  40. package/changelog.d/20260909150000-transport-set-error-redaction.md +1 -0
  41. package/docker-compose.dev.yml +19 -0
  42. package/docker-compose.reverse-gateway.yml +36 -0
  43. package/docker-compose.yml +73 -0
  44. package/docs/architecture.md +264 -0
  45. package/docs/docker-topology.md +164 -0
  46. package/docs/docker.md +281 -0
  47. package/docs/logging.md +185 -0
  48. package/docs/plans/initial-implementation.md +205 -0
  49. package/docs/plans/socket-docker-integration.md +221 -0
  50. package/docs/protocol.md +558 -0
  51. package/docs/releasing.md +18 -0
  52. package/docs/reverse-gateway.md +186 -0
  53. package/docs/runbooks/jsonl-integrity-rollout.md +144 -0
  54. package/docs/running.md +215 -0
  55. package/docs/security.md +258 -0
  56. package/docs/session-lifecycle.md +127 -0
  57. package/docs/socket-api.md +448 -0
  58. package/eslint.config.js +36 -0
  59. package/package.json +44 -0
  60. package/scripts/deploy-gateway.js +194 -0
  61. package/scripts/test.js +28 -0
  62. package/src/auth/passwords.js +38 -0
  63. package/src/auth/static-token-store.js +41 -0
  64. package/src/auth/user-store.js +139 -0
  65. package/src/client/connect.js +76 -0
  66. package/src/client/deferred-virtual-socket.js +312 -0
  67. package/src/client/http-agent.js +101 -0
  68. package/src/client/https-agent.js +366 -0
  69. package/src/client/multiplexed-connection.js +1504 -0
  70. package/src/client/multiplexed-transport-set.js +917 -0
  71. package/src/client/multiplexed.js +3 -0
  72. package/src/client/socketduct-socket.js +1174 -0
  73. package/src/client/virtual-socket.js +256 -0
  74. package/src/config/environment.js +400 -0
  75. package/src/edge/tcp-edge.js +82 -0
  76. package/src/index.js +101 -0
  77. package/src/logging/structured-logger.js +745 -0
  78. package/src/protocol/compression.js +325 -0
  79. package/src/protocol/frame.js +341 -0
  80. package/src/protocol/v3-compression.js +44 -0
  81. package/src/protocol/v3-frame.js +209 -0
  82. package/src/proxy/multiplexed-relay.js +798 -0
  83. package/src/proxy/tcp-relay.js +1191 -0
  84. package/src/relay.js +3 -0
  85. package/src/reverse/client.js +721 -0
  86. package/src/reverse/common.js +88 -0
  87. package/src/reverse/gateway.js +663 -0
  88. package/src/reverse/hub.js +563 -0
  89. package/src/reverse/index.js +3 -0
  90. package/src/reverse/runtime.js +78 -0
  91. package/src/server/control-handler.js +170 -0
  92. package/src/server/primary.js +64 -0
  93. package/src/server/relay-runtime.js +124 -0
  94. package/src/server/worker.js +39 -0
  95. package/src/sessions/session.js +212 -0
  96. package/src/spool/spool-file.js +451 -0
  97. package/tensorbuzz.yml +36 -0
  98. package/test/e2e/gateway-process.test.js +262 -0
  99. package/test/e2e/reverse-gateway-process.test.js +285 -0
  100. package/test/fixtures/logging/enospc-matrix.mjs +238 -0
  101. package/test/fixtures/logging/enospc-recovery.mjs +146 -0
  102. package/test/fixtures/logging/process-writer.mjs +20 -0
  103. package/test/helpers/tls-certificates.js +115 -0
  104. package/test/integration/initial-target-recovery.test.js +518 -0
  105. package/test/integration/logging-recovery.test.js +163 -0
  106. package/test/integration/multiplexed-compatibility.test.js +254 -0
  107. package/test/integration/multiplexed-corrections.test.js +551 -0
  108. package/test/integration/multiplexed-failures.test.js +339 -0
  109. package/test/integration/multiplexed-transport-set.test.js +456 -0
  110. package/test/integration/multiplexed-transport.test.js +208 -0
  111. package/test/integration/reverse-gateway.test.js +1293 -0
  112. package/test/integration/socketduct-http-agent.test.js +435 -0
  113. package/test/integration/socketduct-https-agent.test.js +669 -0
  114. package/test/integration/stream-compression.test.js +1267 -0
  115. package/test/integration/tcp-forwarding.test.js +2878 -0
  116. package/test/integration/tls-forwarding.test.js +748 -0
  117. package/test/unit/auth/auth.test.js +64 -0
  118. package/test/unit/auth/static-token-store.test.js +14 -0
  119. package/test/unit/client/connect.test.js +58 -0
  120. package/test/unit/client/multiplexed-spool-budget.test.js +309 -0
  121. package/test/unit/client/multiplexed-transport-set.test.js +906 -0
  122. package/test/unit/client/socketduct-socket.test.js +1124 -0
  123. package/test/unit/client/virtual-socket.test.js +98 -0
  124. package/test/unit/config/docker-gateway-files.test.js +274 -0
  125. package/test/unit/config/environment.test.js +507 -0
  126. package/test/unit/index.test.js +78 -0
  127. package/test/unit/logging/structured-logger.test.js +674 -0
  128. package/test/unit/protocol/compression.test.js +421 -0
  129. package/test/unit/protocol/frame.test.js +336 -0
  130. package/test/unit/protocol/v3-compression.test.js +31 -0
  131. package/test/unit/protocol/v3-frame.test.js +57 -0
  132. package/test/unit/release-configuration.test.js +21 -0
  133. package/test/unit/server/control-handler.test.js +291 -0
  134. package/test/unit/server/primary.test.js +59 -0
  135. package/test/unit/server/relay-runtime.test.js +434 -0
  136. package/test/unit/sessions/session.test.js +84 -0
  137. package/test/unit/spool/spool-file.test.js +295 -0
  138. 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`