@provos/ironcurtain 0.12.0 → 0.13.0

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 (211) hide show
  1. package/README.md +14 -12
  2. package/dist/cli.js +6 -0
  3. package/dist/cli.js.map +1 -1
  4. package/dist/config/config-command.d.ts +33 -1
  5. package/dist/config/config-command.js +608 -11
  6. package/dist/config/config-command.js.map +1 -1
  7. package/dist/config/openrouter-catalog.d.ts +46 -0
  8. package/dist/config/openrouter-catalog.js +111 -0
  9. package/dist/config/openrouter-catalog.js.map +1 -0
  10. package/dist/config/openrouter-models-fallback.d.ts +15 -0
  11. package/dist/config/openrouter-models-fallback.js +49 -0
  12. package/dist/config/openrouter-models-fallback.js.map +1 -0
  13. package/dist/config/types.d.ts +8 -0
  14. package/dist/config/user-config.d.ts +133 -7
  15. package/dist/config/user-config.js +234 -5
  16. package/dist/config/user-config.js.map +1 -1
  17. package/dist/daemon/daemon-command.js.map +1 -1
  18. package/dist/daemon/ironcurtain-daemon.js +6 -0
  19. package/dist/daemon/ironcurtain-daemon.js.map +1 -1
  20. package/dist/docker/adapters/claude-code.js +109 -1
  21. package/dist/docker/adapters/claude-code.js.map +1 -1
  22. package/dist/docker/adapters/codex.d.ts +10 -1
  23. package/dist/docker/adapters/codex.js +99 -20
  24. package/dist/docker/adapters/codex.js.map +1 -1
  25. package/dist/docker/adapters/goose.js +38 -2
  26. package/dist/docker/adapters/goose.js.map +1 -1
  27. package/dist/docker/agent-adapter.d.ts +29 -5
  28. package/dist/docker/agent-registry.js +1 -1
  29. package/dist/docker/agent-registry.js.map +1 -1
  30. package/dist/docker/apple-container-manager.d.ts +4 -4
  31. package/dist/docker/apple-container-manager.js +44 -22
  32. package/dist/docker/apple-container-manager.js.map +1 -1
  33. package/dist/docker/ca.js +9 -2
  34. package/dist/docker/ca.js.map +1 -1
  35. package/dist/docker/container-lifecycle.js +9 -0
  36. package/dist/docker/container-lifecycle.js.map +1 -1
  37. package/dist/docker/docker-agent-session.d.ts +31 -0
  38. package/dist/docker/docker-agent-session.js +67 -6
  39. package/dist/docker/docker-agent-session.js.map +1 -1
  40. package/dist/docker/docker-infrastructure.d.ts +55 -15
  41. package/dist/docker/docker-infrastructure.js +261 -61
  42. package/dist/docker/docker-infrastructure.js.map +1 -1
  43. package/dist/docker/docker-manager.js +127 -0
  44. package/dist/docker/docker-manager.js.map +1 -1
  45. package/dist/docker/docker-resource-lifecycle.d.ts +71 -0
  46. package/dist/docker/docker-resource-lifecycle.js +454 -0
  47. package/dist/docker/docker-resource-lifecycle.js.map +1 -0
  48. package/dist/docker/gc-command.d.ts +2 -0
  49. package/dist/docker/gc-command.js +37 -0
  50. package/dist/docker/gc-command.js.map +1 -0
  51. package/dist/docker/mitm-proxy.d.ts +6 -4
  52. package/dist/docker/mitm-proxy.js +105 -17
  53. package/dist/docker/mitm-proxy.js.map +1 -1
  54. package/dist/docker/network-topology.d.ts +16 -9
  55. package/dist/docker/network-topology.js +17 -10
  56. package/dist/docker/network-topology.js.map +1 -1
  57. package/dist/docker/openrouter.d.ts +107 -0
  58. package/dist/docker/openrouter.js +236 -0
  59. package/dist/docker/openrouter.js.map +1 -0
  60. package/dist/docker/orientation.js +1 -1
  61. package/dist/docker/orientation.js.map +1 -1
  62. package/dist/docker/platform.d.ts +3 -1
  63. package/dist/docker/platform.js +3 -1
  64. package/dist/docker/platform.js.map +1 -1
  65. package/dist/docker/provider-config.d.ts +6 -0
  66. package/dist/docker/provider-config.js.map +1 -1
  67. package/dist/docker/pty-session.d.ts +7 -0
  68. package/dist/docker/pty-session.js +111 -29
  69. package/dist/docker/pty-session.js.map +1 -1
  70. package/dist/docker/pty-types.d.ts +15 -0
  71. package/dist/docker/pty-types.js +8 -0
  72. package/dist/docker/pty-types.js.map +1 -1
  73. package/dist/docker/sse-extractor.js +55 -5
  74. package/dist/docker/sse-extractor.js.map +1 -1
  75. package/dist/docker/stream-delay.d.ts +86 -0
  76. package/dist/docker/stream-delay.js +218 -0
  77. package/dist/docker/stream-delay.js.map +1 -0
  78. package/dist/docker/token-stream-types.d.ts +15 -0
  79. package/dist/docker/trajectory-reassembler.d.ts +2 -2
  80. package/dist/docker/trajectory-reassembler.js +22 -2
  81. package/dist/docker/trajectory-reassembler.js.map +1 -1
  82. package/dist/docker/trajectory-tap.js +2 -2
  83. package/dist/docker/trajectory-tap.js.map +1 -1
  84. package/dist/docker/types.d.ts +63 -5
  85. package/dist/doctor/checks.d.ts +3 -3
  86. package/dist/doctor/checks.js +28 -11
  87. package/dist/doctor/checks.js.map +1 -1
  88. package/dist/doctor/doctor-command.js +1 -1
  89. package/dist/doctor/doctor-command.js.map +1 -1
  90. package/dist/escalation/escalation-watcher.js +6 -0
  91. package/dist/escalation/escalation-watcher.js.map +1 -1
  92. package/dist/{mux → escalation}/trusted-input.d.ts +7 -4
  93. package/dist/{mux → escalation}/trusted-input.js +8 -5
  94. package/dist/escalation/trusted-input.js.map +1 -0
  95. package/dist/hash.js.map +1 -1
  96. package/dist/index.js +37 -6
  97. package/dist/index.js.map +1 -1
  98. package/dist/mux/mux-app.d.ts +7 -0
  99. package/dist/mux/mux-app.js +17 -16
  100. package/dist/mux/mux-app.js.map +1 -1
  101. package/dist/mux/mux-command.js +8 -3
  102. package/dist/mux/mux-command.js.map +1 -1
  103. package/dist/mux/mux-input-handler.d.ts +26 -2
  104. package/dist/mux/mux-input-handler.js +93 -11
  105. package/dist/mux/mux-input-handler.js.map +1 -1
  106. package/dist/mux/mux-renderer.d.ts +2 -1
  107. package/dist/mux/mux-renderer.js +67 -0
  108. package/dist/mux/mux-renderer.js.map +1 -1
  109. package/dist/mux/provider-profile-snapshot.d.ts +44 -0
  110. package/dist/mux/provider-profile-snapshot.js +56 -0
  111. package/dist/mux/provider-profile-snapshot.js.map +1 -0
  112. package/dist/mux/types.d.ts +3 -2
  113. package/dist/mux/types.js +6 -2
  114. package/dist/mux/types.js.map +1 -1
  115. package/dist/observe/observe-command.js.map +1 -1
  116. package/dist/pipeline/constitution-compiler.js.map +1 -1
  117. package/dist/pipeline/generate-with-repair.js.map +1 -1
  118. package/dist/pipeline/refresh-lists.js.map +1 -1
  119. package/dist/pipeline/scenario-schema-validator.js.map +1 -1
  120. package/dist/{mux → pty}/pty-bridge.d.ts +39 -3
  121. package/dist/{mux → pty}/pty-bridge.js +68 -18
  122. package/dist/pty/pty-bridge.js.map +1 -0
  123. package/dist/pty/resolve-ironcurtain-bin.d.ts +17 -0
  124. package/dist/pty/resolve-ironcurtain-bin.js +22 -0
  125. package/dist/pty/resolve-ironcurtain-bin.js.map +1 -0
  126. package/dist/servers/fetch-server.js +2 -0
  127. package/dist/servers/fetch-server.js.map +1 -1
  128. package/dist/session/index.d.ts +1 -1
  129. package/dist/session/index.js +11 -2
  130. package/dist/session/index.js.map +1 -1
  131. package/dist/session/preflight.d.ts +19 -5
  132. package/dist/session/preflight.js +41 -25
  133. package/dist/session/preflight.js.map +1 -1
  134. package/dist/session/resource-budget-tracker.js +8 -0
  135. package/dist/session/resource-budget-tracker.js.map +1 -1
  136. package/dist/session/session-manager.d.ts +7 -0
  137. package/dist/session/session-manager.js.map +1 -1
  138. package/dist/session/types.d.ts +14 -0
  139. package/dist/signal/signal-bot-daemon.d.ts +1 -0
  140. package/dist/signal/signal-bot-daemon.js +9 -2
  141. package/dist/signal/signal-bot-daemon.js.map +1 -1
  142. package/dist/trusted-process/mcp-error-utils.js +4 -1
  143. package/dist/trusted-process/mcp-error-utils.js.map +1 -1
  144. package/dist/trusted-process/mcp-proxy-server.js +2 -0
  145. package/dist/trusted-process/mcp-proxy-server.js.map +1 -1
  146. package/dist/trusted-process/policy-engine.js.map +1 -1
  147. package/dist/trusted-process/tcp-server-transport.d.ts +7 -0
  148. package/dist/trusted-process/tcp-server-transport.js +48 -10
  149. package/dist/trusted-process/tcp-server-transport.js.map +1 -1
  150. package/dist/utils/preflight-checks.js +1 -3
  151. package/dist/utils/preflight-checks.js.map +1 -1
  152. package/dist/utils/stdio-guard.d.ts +1 -0
  153. package/dist/utils/stdio-guard.js +27 -0
  154. package/dist/utils/stdio-guard.js.map +1 -0
  155. package/dist/web-ui/__tests__/config-dispatch.test.d.ts +13 -0
  156. package/dist/web-ui/__tests__/config-dispatch.test.js +383 -0
  157. package/dist/web-ui/__tests__/config-dispatch.test.js.map +1 -0
  158. package/dist/web-ui/__tests__/json-rpc-dispatch.test.js +6 -0
  159. package/dist/web-ui/__tests__/json-rpc-dispatch.test.js.map +1 -1
  160. package/dist/web-ui/dispatch/config-dispatch.d.ts +15 -0
  161. package/dist/web-ui/dispatch/config-dispatch.js +277 -0
  162. package/dist/web-ui/dispatch/config-dispatch.js.map +1 -0
  163. package/dist/web-ui/dispatch/escalation-dispatch.js +11 -2
  164. package/dist/web-ui/dispatch/escalation-dispatch.js.map +1 -1
  165. package/dist/web-ui/dispatch/pty-dispatch.d.ts +15 -0
  166. package/dist/web-ui/dispatch/pty-dispatch.js +66 -0
  167. package/dist/web-ui/dispatch/pty-dispatch.js.map +1 -0
  168. package/dist/web-ui/dispatch/session-dispatch.js +69 -4
  169. package/dist/web-ui/dispatch/session-dispatch.js.map +1 -1
  170. package/dist/web-ui/dispatch/types.d.ts +12 -0
  171. package/dist/web-ui/dispatch/types.js +38 -1
  172. package/dist/web-ui/dispatch/types.js.map +1 -1
  173. package/dist/web-ui/dispatch/workflow-dispatch.js.map +1 -1
  174. package/dist/web-ui/json-rpc-dispatch.js +3 -0
  175. package/dist/web-ui/json-rpc-dispatch.js.map +1 -1
  176. package/dist/web-ui/pty-session-manager.d.ts +234 -0
  177. package/dist/web-ui/pty-session-manager.js +599 -0
  178. package/dist/web-ui/pty-session-manager.js.map +1 -0
  179. package/dist/web-ui/web-event-bus.d.ts +9 -0
  180. package/dist/web-ui/web-event-bus.js.map +1 -1
  181. package/dist/web-ui/web-session-transport.js.map +1 -1
  182. package/dist/web-ui/web-ui-server.d.ts +8 -0
  183. package/dist/web-ui/web-ui-server.js +25 -0
  184. package/dist/web-ui/web-ui-server.js.map +1 -1
  185. package/dist/web-ui/web-ui-types.d.ts +80 -1
  186. package/dist/web-ui/web-ui-types.js.map +1 -1
  187. package/dist/web-ui-static/assets/index-CCVI4nEK.css +1 -0
  188. package/dist/web-ui-static/assets/index-Dm012gvY.js +114 -0
  189. package/dist/web-ui-static/index.html +2 -2
  190. package/dist/workflow/daemon-gate-commands.js +38 -42
  191. package/dist/workflow/daemon-gate-commands.js.map +1 -1
  192. package/dist/workflow/machine-builder.js.map +1 -1
  193. package/dist/workflow/orchestrator.js +10 -7
  194. package/dist/workflow/orchestrator.js.map +1 -1
  195. package/dist/workflow/shutdown-signals.d.ts +7 -0
  196. package/dist/workflow/shutdown-signals.js +40 -0
  197. package/dist/workflow/shutdown-signals.js.map +1 -0
  198. package/dist/workflow/validate.js.map +1 -1
  199. package/dist/workflow/workflow-command.js +10 -8
  200. package/dist/workflow/workflow-command.js.map +1 -1
  201. package/dist/workflow/workflows/evolve/README.md +66 -0
  202. package/dist/workflow/workflows/vuln-discovery/README.md +54 -0
  203. package/docker/entrypoint-claude-code.sh +22 -0
  204. package/package.json +31 -27
  205. package/src/workflow/workflows/evolve/README.md +66 -0
  206. package/src/workflow/workflows/vuln-discovery/README.md +54 -0
  207. package/dist/mux/pty-bridge.js.map +0 -1
  208. package/dist/mux/trusted-input.js.map +0 -1
  209. package/dist/web-ui-static/assets/index-BD5U6ILh.css +0 -1
  210. package/dist/web-ui-static/assets/index-FMsHWEfK.js +0 -79
  211. package/packages/web-ui/README.md +0 -113
@@ -0,0 +1,454 @@
1
+ /**
2
+ * Crash-safe ownership, reconciliation, and IPv4 allocation for Docker
3
+ * resources created by IronCurtain.
4
+ *
5
+ * Docker intentionally outlives its CLI clients. A killed IronCurtain process
6
+ * therefore leaves containers and networks behind unless a later process can
7
+ * prove ownership and reclaim them. Labels plus a host-side owner lease provide
8
+ * that proof without confusing a concurrently-starting empty network for an
9
+ * orphan.
10
+ */
11
+ import { createHash, randomUUID } from 'node:crypto';
12
+ import { execFileSync } from 'node:child_process';
13
+ import { closeSync, mkdirSync, openSync, readFileSync, rmSync, unlinkSync, writeFileSync } from 'node:fs';
14
+ import { networkInterfaces, platform } from 'node:os';
15
+ import { resolve } from 'node:path';
16
+ import { getIronCurtainHome } from '../config/paths.js';
17
+ import * as logger from '../logger.js';
18
+ import { isExecError } from '../utils/exec-error.js';
19
+ export const IRONCURTAIN_MANAGED_LABEL = 'ironcurtain.managed';
20
+ export const IRONCURTAIN_OWNER_PID_LABEL = 'ironcurtain.owner-pid';
21
+ export const IRONCURTAIN_OWNER_TOKEN_LABEL = 'ironcurtain.owner-token';
22
+ export const IRONCURTAIN_CREATED_AT_LABEL = 'ironcurtain.created-at';
23
+ export const IRONCURTAIN_RESOURCE_SCHEMA_LABEL = 'ironcurtain.resource-schema';
24
+ const IRONCURTAIN_BUNDLE_LABEL = 'ironcurtain.bundle';
25
+ const RESOURCE_SCHEMA = '2';
26
+ // Current bundle slugs are 12 hex digits; pre-identity-refactor names used a
27
+ // raw UUID substring and therefore contain a hyphen after eight digits.
28
+ const LEGACY_NETWORK_RE = /^ironcurtain-(?:[a-f0-9]{12}|[a-f0-9]{8}-[a-f0-9]{3})$/;
29
+ const LEGACY_EMPTY_NETWORK_GRACE_MS = 2 * 60_000;
30
+ const ownerLeases = new Map();
31
+ let exitHookInstalled = false;
32
+ let cachedBootId;
33
+ function currentBootId() {
34
+ if (cachedBootId)
35
+ return cachedBootId;
36
+ try {
37
+ if (platform() === 'linux') {
38
+ cachedBootId = readFileSync('/proc/sys/kernel/random/boot_id', 'utf8').trim();
39
+ }
40
+ else if (platform() === 'darwin') {
41
+ const bootTime = execFileSync('sysctl', ['-n', 'kern.boottime'], {
42
+ encoding: 'utf8',
43
+ timeout: 1_000,
44
+ stdio: ['ignore', 'pipe', 'ignore'],
45
+ });
46
+ const match = bootTime.match(/sec\s*=\s*(\d+),\s*usec\s*=\s*(\d+)/);
47
+ if (match)
48
+ cachedBootId = `darwin:${match[1]}.${match[2]}`;
49
+ }
50
+ }
51
+ catch {
52
+ // Process start time remains sufficient to distinguish recycled PIDs.
53
+ }
54
+ cachedBootId ||= `${platform()}:unknown-boot`;
55
+ return cachedBootId;
56
+ }
57
+ function defaultProcessIdentity(pid) {
58
+ try {
59
+ const startedAt = execFileSync('ps', ['-o', 'lstart=', '-p', String(pid)], {
60
+ encoding: 'utf8',
61
+ timeout: 1_000,
62
+ stdio: ['ignore', 'pipe', 'ignore'],
63
+ env: { ...process.env, LC_ALL: 'C', TZ: 'UTC' },
64
+ }).trim();
65
+ if (!startedAt)
66
+ return undefined;
67
+ return { bootId: currentBootId(), startedAt };
68
+ }
69
+ catch {
70
+ return undefined;
71
+ }
72
+ }
73
+ function leaseRoot() {
74
+ return resolve(getIronCurtainHome(), 'run', 'docker-owners');
75
+ }
76
+ function installExitHook() {
77
+ if (exitHookInstalled)
78
+ return;
79
+ exitHookInstalled = true;
80
+ process.once('exit', () => {
81
+ for (const lease of ownerLeases.values()) {
82
+ try {
83
+ unlinkSync(lease.path);
84
+ }
85
+ catch {
86
+ // A crash reconciler may already have removed it.
87
+ }
88
+ }
89
+ });
90
+ }
91
+ function ownerLeaseKey(root, bundleId) {
92
+ return `${root}\0${bundleId}`;
93
+ }
94
+ function getOwnerLease(bundleId) {
95
+ const root = leaseRoot();
96
+ const key = ownerLeaseKey(root, bundleId);
97
+ const existing = ownerLeases.get(key);
98
+ if (existing)
99
+ return existing;
100
+ mkdirSync(root, { recursive: true, mode: 0o700 });
101
+ const token = randomUUID();
102
+ const path = resolve(root, `${token}.json`);
103
+ const identity = defaultProcessIdentity(process.pid);
104
+ if (!identity)
105
+ throw new Error(`Unable to determine the identity of owner process ${process.pid}`);
106
+ const lease = { token, pid: process.pid, identity, path };
107
+ writeFileSync(path, JSON.stringify({ token, pid: process.pid, identity, bundleId, createdAt: new Date().toISOString() }), { mode: 0o600, flag: 'wx' });
108
+ ownerLeases.set(key, lease);
109
+ installExitHook();
110
+ return lease;
111
+ }
112
+ /** Labels stamped on every managed container and network. */
113
+ export function managedResourceLabels(bundleId) {
114
+ const lease = getOwnerLease(bundleId);
115
+ return {
116
+ [IRONCURTAIN_MANAGED_LABEL]: 'true',
117
+ [IRONCURTAIN_BUNDLE_LABEL]: bundleId,
118
+ [IRONCURTAIN_OWNER_PID_LABEL]: String(lease.pid),
119
+ [IRONCURTAIN_OWNER_TOKEN_LABEL]: lease.token,
120
+ [IRONCURTAIN_CREATED_AT_LABEL]: new Date().toISOString(),
121
+ [IRONCURTAIN_RESOURCE_SCHEMA_LABEL]: RESOURCE_SCHEMA,
122
+ };
123
+ }
124
+ /** Marks a completed/failed bundle as no longer live so same-process GC can reclaim a failed teardown. */
125
+ export function releaseManagedResourceLease(bundleId) {
126
+ const root = leaseRoot();
127
+ const key = ownerLeaseKey(root, bundleId);
128
+ const lease = ownerLeases.get(key);
129
+ if (!lease)
130
+ return;
131
+ ownerLeases.delete(key);
132
+ try {
133
+ unlinkSync(lease.path);
134
+ }
135
+ catch {
136
+ // Already reclaimed or removed during shutdown.
137
+ }
138
+ }
139
+ function defaultPidAlive(pid) {
140
+ try {
141
+ process.kill(pid, 0);
142
+ return true;
143
+ }
144
+ catch (error) {
145
+ return error.code === 'EPERM';
146
+ }
147
+ }
148
+ function ownerIsAlive(labels, pidAlive, processIdentity, root = leaseRoot()) {
149
+ const pid = Number(labels[IRONCURTAIN_OWNER_PID_LABEL]);
150
+ const token = labels[IRONCURTAIN_OWNER_TOKEN_LABEL];
151
+ if (!Number.isSafeInteger(pid) || pid <= 0 || !token || !pidAlive(pid))
152
+ return false;
153
+ try {
154
+ const lease = JSON.parse(readFileSync(resolve(root, `${token}.json`), 'utf8'));
155
+ if (lease.token !== token ||
156
+ lease.pid !== pid ||
157
+ typeof lease.identity?.bootId !== 'string' ||
158
+ typeof lease.identity.startedAt !== 'string') {
159
+ return false;
160
+ }
161
+ const currentIdentity = processIdentity(pid);
162
+ return (currentIdentity !== undefined &&
163
+ currentIdentity.bootId === lease.identity.bootId &&
164
+ currentIdentity.startedAt === lease.identity.startedAt);
165
+ }
166
+ catch {
167
+ return false;
168
+ }
169
+ }
170
+ function resourceAgeMs(created, now) {
171
+ const timestamp = Date.parse(created);
172
+ return Number.isFinite(timestamp) ? Math.max(0, now.getTime() - timestamp) : Number.POSITIVE_INFINITY;
173
+ }
174
+ async function withReconcileLock(fn, processIdentity) {
175
+ const root = leaseRoot();
176
+ mkdirSync(root, { recursive: true, mode: 0o700 });
177
+ const lockPath = resolve(root, 'reconcile.lock');
178
+ let fd;
179
+ try {
180
+ try {
181
+ fd = openSync(lockPath, 'wx', 0o600);
182
+ writeFileSync(fd, JSON.stringify({ pid: process.pid, identity: processIdentity(process.pid) }));
183
+ }
184
+ catch (error) {
185
+ if (error.code !== 'EEXIST')
186
+ throw error;
187
+ try {
188
+ const owner = JSON.parse(readFileSync(lockPath, 'utf8'));
189
+ const currentIdentity = typeof owner.pid === 'number' ? processIdentity(owner.pid) : undefined;
190
+ if (typeof owner.pid === 'number' &&
191
+ defaultPidAlive(owner.pid) &&
192
+ currentIdentity !== undefined &&
193
+ owner.identity !== undefined &&
194
+ currentIdentity.bootId === owner.identity.bootId &&
195
+ currentIdentity.startedAt === owner.identity.startedAt) {
196
+ return undefined;
197
+ }
198
+ }
199
+ catch {
200
+ // Invalid/stale lock: replace it below.
201
+ }
202
+ rmSync(lockPath, { force: true });
203
+ fd = openSync(lockPath, 'wx', 0o600);
204
+ writeFileSync(fd, JSON.stringify({ pid: process.pid, identity: processIdentity(process.pid) }));
205
+ }
206
+ return await fn();
207
+ }
208
+ finally {
209
+ if (fd !== undefined)
210
+ closeSync(fd);
211
+ if (fd !== undefined)
212
+ rmSync(lockPath, { force: true });
213
+ }
214
+ }
215
+ /**
216
+ * Reclaims resources whose owner process is gone. Unlabeled legacy networks
217
+ * are reclaimed only when empty and old enough; attached legacy resources are
218
+ * deliberately left for an explicit operator action because ownership cannot
219
+ * be proven safely.
220
+ */
221
+ export async function reconcileIronCurtainDockerResources(docker, options = {}) {
222
+ const empty = {
223
+ removedContainers: [],
224
+ removedNetworks: [],
225
+ retainedActiveResources: 0,
226
+ skippedUnsafeNetworks: [],
227
+ };
228
+ if (!docker.listNetworks || !docker.listContainers)
229
+ return empty;
230
+ const identityProbe = options.processIdentity ?? defaultProcessIdentity;
231
+ const identityCache = new Map();
232
+ const processIdentity = (pid) => {
233
+ if (!identityCache.has(pid))
234
+ identityCache.set(pid, identityProbe(pid));
235
+ return identityCache.get(pid);
236
+ };
237
+ const result = await withReconcileLock(async () => {
238
+ const pidAlive = options.pidAlive ?? defaultPidAlive;
239
+ const now = options.now ?? new Date();
240
+ const removedContainers = [];
241
+ const removedNetworks = [];
242
+ const skippedUnsafeNetworks = [];
243
+ const deadOwnerTokens = new Set();
244
+ let retainedActiveResources = 0;
245
+ const managedContainers = await docker.listContainers?.({ labelFilter: `${IRONCURTAIN_MANAGED_LABEL}=true` });
246
+ for (const container of managedContainers ?? []) {
247
+ if (ownerIsAlive(container.labels, pidAlive, processIdentity)) {
248
+ retainedActiveResources++;
249
+ continue;
250
+ }
251
+ const ownerToken = container.labels[IRONCURTAIN_OWNER_TOKEN_LABEL];
252
+ if (ownerToken)
253
+ deadOwnerTokens.add(ownerToken);
254
+ logger.warn(`[docker-gc] reclaiming orphaned container ${container.name}`);
255
+ if (!options.dryRun) {
256
+ await docker.remove(container.id);
257
+ if (await docker.containerExists(container.id)) {
258
+ logger.warn(`[docker-gc] container ${container.name} still exists after forced removal`);
259
+ continue;
260
+ }
261
+ }
262
+ removedContainers.push(container.name);
263
+ }
264
+ const removedContainerIds = new Set((managedContainers ?? [])
265
+ .filter((container) => removedContainers.includes(container.name))
266
+ .map((container) => container.id));
267
+ const networks = await docker.listNetworks?.();
268
+ for (const network of networks ?? []) {
269
+ const managed = network.labels[IRONCURTAIN_MANAGED_LABEL] === 'true';
270
+ const legacy = !managed && LEGACY_NETWORK_RE.test(network.name);
271
+ if (!managed && !legacy)
272
+ continue;
273
+ if (managed && ownerIsAlive(network.labels, pidAlive, processIdentity)) {
274
+ retainedActiveResources++;
275
+ continue;
276
+ }
277
+ const ownerToken = network.labels[IRONCURTAIN_OWNER_TOKEN_LABEL];
278
+ if (managed && ownerToken)
279
+ deadOwnerTokens.add(ownerToken);
280
+ if (legacy) {
281
+ const graceMs = options.legacyGraceMs ?? LEGACY_EMPTY_NETWORK_GRACE_MS;
282
+ if (network.containerIds.length > 0 || resourceAgeMs(network.created, now) < graceMs) {
283
+ skippedUnsafeNetworks.push(network.name);
284
+ continue;
285
+ }
286
+ }
287
+ const survivingAttachments = network.containerIds.filter((id) => !removedContainerIds.has(id));
288
+ if (survivingAttachments.length > 0) {
289
+ logger.warn(`[docker-gc] refusing to remove ${network.name}: it has non-orphan attachments`);
290
+ skippedUnsafeNetworks.push(network.name);
291
+ continue;
292
+ }
293
+ logger.warn(`[docker-gc] reclaiming orphaned network ${network.name}`);
294
+ if (!options.dryRun) {
295
+ await docker.removeNetwork(network.name);
296
+ if (docker.networkExists && (await docker.networkExists(network.name))) {
297
+ logger.warn(`[docker-gc] network ${network.name} still exists after removal`);
298
+ continue;
299
+ }
300
+ }
301
+ removedNetworks.push(network.name);
302
+ }
303
+ if (!options.dryRun) {
304
+ for (const token of deadOwnerTokens)
305
+ rmSync(resolve(leaseRoot(), `${token}.json`), { force: true });
306
+ }
307
+ return { removedContainers, removedNetworks, retainedActiveResources, skippedUnsafeNetworks };
308
+ }, processIdentity);
309
+ return result ?? empty;
310
+ }
311
+ /** Startup/retry reconciliation must never become a Docker session prerequisite. */
312
+ export async function reconcileIronCurtainDockerResourcesBestEffort(docker, context) {
313
+ try {
314
+ await reconcileIronCurtainDockerResources(docker);
315
+ }
316
+ catch (error) {
317
+ logger.warn(`[docker-gc] ${context} reconciliation skipped: ${error instanceof Error ? error.message : String(error)}`);
318
+ }
319
+ }
320
+ function ipv4ToNumber(address) {
321
+ const octets = address.split('.').map(Number);
322
+ if (octets.length !== 4 || octets.some((octet) => !Number.isInteger(octet) || octet < 0 || octet > 255)) {
323
+ return undefined;
324
+ }
325
+ return (((octets[0] << 24) >>> 0) + (octets[1] << 16) + (octets[2] << 8) + octets[3]) >>> 0;
326
+ }
327
+ function numberToIpv4(value) {
328
+ return [value >>> 24, (value >>> 16) & 255, (value >>> 8) & 255, value & 255].join('.');
329
+ }
330
+ function parseIpv4Cidr(value) {
331
+ const [address, rawPrefix] = value.split('/');
332
+ const prefix = Number(rawPrefix);
333
+ const ip = ipv4ToNumber(address);
334
+ if (ip === undefined || !Number.isInteger(prefix) || prefix < 0 || prefix > 32)
335
+ return undefined;
336
+ const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
337
+ return { network: (ip & mask) >>> 0, prefix };
338
+ }
339
+ function cidrsOverlap(left, right) {
340
+ const prefix = Math.min(left.prefix, right.prefix);
341
+ const mask = prefix === 0 ? 0 : (0xffffffff << (32 - prefix)) >>> 0;
342
+ return (left.network & mask) === (right.network & mask);
343
+ }
344
+ export function hostInterfaceIpv4Cidrs() {
345
+ return Object.values(networkInterfaces())
346
+ .flatMap((entries) => entries ?? [])
347
+ .filter((entry) => entry.family === 'IPv4' && entry.cidr)
348
+ .map((entry) => entry.cidr);
349
+ }
350
+ const DOCKER_SUBNET_PREFIX = 29;
351
+ const ADDRESS_POOLS = ['172.20.0.0/14', '172.24.0.0/14', '172.28.0.0/14', '10.240.0.0/12'];
352
+ /** Returns the allocator pool containing a selected /29. */
353
+ export function dockerAllocationPoolForSubnet(subnet) {
354
+ const candidate = parseIpv4Cidr(subnet);
355
+ if (!candidate)
356
+ return subnet;
357
+ return (ADDRESS_POOLS.find((pool) => {
358
+ const parsed = parseIpv4Cidr(pool);
359
+ return parsed !== undefined && cidrsOverlap(candidate, parsed);
360
+ }) ?? subnet);
361
+ }
362
+ export class InternalNetworkConnectivityError extends Error {
363
+ subnet;
364
+ constructor(message, subnet) {
365
+ super(message);
366
+ this.subnet = subnet;
367
+ this.name = 'InternalNetworkConnectivityError';
368
+ }
369
+ }
370
+ export async function withInternalNetworkAllocationRetry(options, runAttempt) {
371
+ const excludedSubnets = new Set();
372
+ let lastError;
373
+ for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
374
+ try {
375
+ return await runAttempt(excludedSubnets, attempt);
376
+ }
377
+ catch (error) {
378
+ lastError = error;
379
+ if (!(error instanceof InternalNetworkConnectivityError) || !error.subnet || attempt === options.maxAttempts) {
380
+ throw error;
381
+ }
382
+ const rejectedPool = dockerAllocationPoolForSubnet(error.subnet);
383
+ excludedSubnets.add(rejectedPool);
384
+ logger.warn(`${options.description} ${error.subnet} failed its end-to-end checks; rejecting ${rejectedPool} and ` +
385
+ `retrying with another allocation (${attempt}/${options.maxAttempts})`);
386
+ await options.reconcile?.();
387
+ }
388
+ }
389
+ throw lastError;
390
+ }
391
+ function* candidateSubnets(name) {
392
+ const seed = createHash('sha256').update(name).digest().readUInt32BE(0);
393
+ for (const poolValue of ADDRESS_POOLS) {
394
+ const pool = parseIpv4Cidr(poolValue);
395
+ if (!pool)
396
+ continue;
397
+ const count = 2 ** (DOCKER_SUBNET_PREFIX - pool.prefix);
398
+ const offset = seed % count;
399
+ const blockSize = 2 ** (32 - DOCKER_SUBNET_PREFIX);
400
+ for (let index = 0; index < count; index++) {
401
+ const block = (pool.network + ((offset + index) % count) * blockSize) >>> 0;
402
+ yield `${numberToIpv4(block)}/${DOCKER_SUBNET_PREFIX}`;
403
+ }
404
+ }
405
+ }
406
+ function allocationConflict(error) {
407
+ if (!isExecError(error))
408
+ return false;
409
+ return /overlap|address pool|fully subnetted|pool.*exhaust|no available network/i.test(error.stderr);
410
+ }
411
+ /** Allocates a small internal subnet while never falling back into 192.168/16. */
412
+ export async function createIronCurtainInternalNetwork(docker, name, bundleId, options = {}) {
413
+ const networks = (await docker.listNetworks?.()) ?? [];
414
+ const sameNamedNetwork = networks.find((network) => network.name === name);
415
+ if (sameNamedNetwork) {
416
+ throw new Error(`Docker network ${name} already exists (${sameNamedNetwork.subnets.join(', ') || 'unknown subnet'}). ` +
417
+ `Refusing to reuse it because its requested ownership/subnet cannot be verified.`);
418
+ }
419
+ const occupied = [
420
+ ...networks.flatMap((network) => network.subnets),
421
+ ...(options.hostCidrs ?? hostInterfaceIpv4Cidrs()),
422
+ ]
423
+ .map(parseIpv4Cidr)
424
+ .filter((cidr) => cidr !== undefined);
425
+ const excluded = [...(options.excludedSubnets ?? [])]
426
+ .map(parseIpv4Cidr)
427
+ .filter((cidr) => cidr !== undefined);
428
+ let lastConflict;
429
+ for (const subnet of candidateSubnets(name)) {
430
+ const candidate = parseIpv4Cidr(subnet);
431
+ if (!candidate ||
432
+ excluded.some((cidr) => cidrsOverlap(candidate, cidr)) ||
433
+ occupied.some((cidr) => cidrsOverlap(candidate, cidr))) {
434
+ continue;
435
+ }
436
+ try {
437
+ await docker.createNetwork(name, {
438
+ internal: true,
439
+ subnet,
440
+ labels: managedResourceLabels(bundleId),
441
+ });
442
+ return { name, subnet };
443
+ }
444
+ catch (error) {
445
+ if (!allocationConflict(error))
446
+ throw error;
447
+ lastConflict = error;
448
+ occupied.push(candidate);
449
+ }
450
+ }
451
+ throw new Error(`No collision-free IronCurtain Docker subnet is available for ${name}. ` +
452
+ `Reconciled the managed resources and searched /29 networks outside 192.168.0.0/16.`, { cause: lastConflict });
453
+ }
454
+ //# sourceMappingURL=docker-resource-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-resource-lifecycle.js","sourceRoot":"","sources":["../../src/docker/docker-resource-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ /** Explicit operator surface for inspecting or applying the startup reconciler. */
2
+ export declare function runDockerGcCommand(args: readonly string[]): Promise<void>;
@@ -0,0 +1,37 @@
1
+ import { parseArgs } from 'node:util';
2
+ import { createDockerManager } from './docker-manager.js';
3
+ import { reconcileIronCurtainDockerResources } from './docker-resource-lifecycle.js';
4
+ /** Explicit operator surface for inspecting or applying the startup reconciler. */
5
+ export async function runDockerGcCommand(args) {
6
+ const { values } = parseArgs({
7
+ args: [...args],
8
+ options: {
9
+ 'dry-run': { type: 'boolean' },
10
+ force: { type: 'boolean' },
11
+ help: { type: 'boolean', short: 'h' },
12
+ },
13
+ strict: true,
14
+ });
15
+ if (values.help) {
16
+ process.stdout.write('Usage: ironcurtain gc [--dry-run | --force]\n\n' +
17
+ 'Lists crash-orphaned IronCurtain Docker resources by default.\n' +
18
+ 'Use --force to remove resources whose owner process is no longer alive.\n');
19
+ return;
20
+ }
21
+ if (values.force && values['dry-run'])
22
+ throw new Error('Choose either --dry-run or --force, not both');
23
+ const apply = values.force === true;
24
+ const result = await reconcileIronCurtainDockerResources(createDockerManager(), { dryRun: !apply });
25
+ const verb = apply ? 'Reclaimed' : 'Would reclaim';
26
+ process.stdout.write(`${verb} ${result.removedContainers.length} container(s) and ${result.removedNetworks.length} network(s).\n`);
27
+ for (const name of result.removedContainers)
28
+ process.stdout.write(` container ${name}\n`);
29
+ for (const name of result.removedNetworks)
30
+ process.stdout.write(` network ${name}\n`);
31
+ if (result.skippedUnsafeNetworks.length > 0) {
32
+ process.stdout.write(`Skipped ${result.skippedUnsafeNetworks.length} legacy/attached network(s) with uncertain ownership.\n`);
33
+ }
34
+ if (!apply)
35
+ process.stdout.write('Re-run with --force to apply this plan.\n');
36
+ }
37
+ //# sourceMappingURL=gc-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc-command.js","sourceRoot":"","sources":["../../src/docker/gc-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AAErF,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAuB;IAC9D,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;QAC3B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAC;QACf,OAAO,EAAE;YACP,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;YAC9B,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;YAC1B,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;SACtC;QACD,MAAM,EAAE,IAAI;KACb,CAAC,CAAC;IACH,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iDAAiD;YAC/C,iEAAiE;YACjE,2EAA2E,CAC9E,CAAC;QACF,OAAO;IACT,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,SAAS,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAEvG,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,mCAAmC,CAAC,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;IACpG,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC;IACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,GAAG,IAAI,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,qBAAqB,MAAM,CAAC,eAAe,CAAC,MAAM,gBAAgB,CAC7G,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,iBAAiB;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC;IAC3F,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,eAAe;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC;IACzF,IAAI,MAAM,CAAC,qBAAqB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,WAAW,MAAM,CAAC,qBAAqB,CAAC,MAAM,yDAAyD,CACxG,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;AAChF,CAAC"}
@@ -238,11 +238,13 @@ export interface BoundedJsonResponseCapture {
238
238
  */
239
239
  export declare function createBoundedJsonResponseCapture(maxBytes?: number): BoundedJsonResponseCapture;
240
240
  /**
241
- * Maps a target hostname to the SSE provider for token stream parsing.
242
- * Only Anthropic and OpenAI hosts are recognized; everything else
243
- * falls back to 'unknown'.
241
+ * Maps a target hostname (and, for OpenRouter, request path) to the SSE
242
+ * provider for token stream parsing. Anthropic and OpenAI hosts classify by
243
+ * host alone; `openrouter.ai` serves three wire formats depending on path, so
244
+ * `/api/v1/messages` (the Anthropic skin) is 'anthropic' and every other path
245
+ * is 'openai'. Everything else falls back to 'unknown'.
244
246
  */
245
- export declare function resolveSseProvider(hostname: string): SseProvider;
247
+ export declare function resolveSseProvider(hostname: string, path?: string): SseProvider;
246
248
  export declare function extractToolResults(parsed: Record<string, unknown>, sessionId: import('../session/types.js').SessionId): void;
247
249
  /**
248
250
  * Extract token stream events from a non-streaming JSON response body.