feat(foundry): memory investigation tooling and VFS pool spec

Add memory monitoring instrumentation, investigation findings, and
SQLite VFS pool design spec for addressing WASM SQLite memory spikes.

- Add /debug/memory endpoint and periodic memory logging (dev only)
- Add mem-monitor.sh script for continuous memory profiling with
  automatic heap snapshot capture on spike detection
- Add configureRunnerPool to registry setup for engine driver support
- Document memory investigation findings (per-actor cost, spike behavior)
- Write SQLite VFS pool spec for bin-packing actors onto shared WASM instances
- Add foundry-mem-monitor and foundry-dev-engine justfile recipes
- Add compose.dev.yaml engine driver and platform support

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nathan Flurry 2026-03-17 23:46:03 -07:00
parent 7b23e519c2
commit ee99d0b318
18 changed files with 888 additions and 496 deletions

122
pnpm-lock.yaml generated
View file

@ -542,8 +542,8 @@ importers:
specifier: ^19.1.1
version: 19.2.4
rivetkit:
specifier: 2.1.6
version: 2.1.6(@hono/node-server@1.19.9(hono@4.12.2))(@hono/node-ws@1.3.0(@hono/node-server@1.19.9(hono@4.12.2))(hono@4.12.2))(@standard-schema/spec@1.1.0)(drizzle-kit@0.31.9)(drizzle-orm@0.44.7(@cloudflare/workers-types@4.20260317.1)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.18.0)(better-sqlite3@11.10.0)(bun-types@1.3.10)(kysely@0.28.11)(pg@8.20.0))(ws@8.19.0)
specifier: https://pkg.pr.new/rivet-dev/rivet/rivetkit@791500a
version: https://pkg.pr.new/rivet-dev/rivet/rivetkit@791500a(@e2b/code-interpreter@2.3.3)(@hono/node-server@1.19.9(hono@4.12.2))(@hono/node-ws@1.3.0(@hono/node-server@1.19.9(hono@4.12.2))(hono@4.12.2))(@standard-schema/spec@1.1.0)(dockerode@4.0.9)(drizzle-kit@0.31.9)(drizzle-orm@0.44.7(@cloudflare/workers-types@4.20260317.1)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.18.0)(bun-types@1.3.10)(kysely@0.28.11)(pg@8.20.0))(ws@8.19.0)
sandbox-agent:
specifier: workspace:*
version: link:../../../sdks/typescript
@ -3029,16 +3029,10 @@ packages:
resolution: {integrity: sha512-3qndQUQXLdwafMEqfhz24hUtDPcsf1Bu3q52Kb8MqeH8JUh3h6R4HYW3ZJXiQsLcyYyFM68PuIwlLRlg1xDEpg==}
engines: {node: ^14.18.0 || >=16.0.0}
'@rivetkit/engine-runner-protocol@2.1.6':
resolution: {integrity: sha512-QwaWvAJN2KGae+UHKZbLiEWaWj9ycmwtrRtUq728CU+lidkaGv5yHxXb4gkXSD7rhGQcR98+XWZLb0F0BM/vAg==}
'@rivetkit/engine-runner-protocol@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd}
version: 2.1.6
'@rivetkit/engine-runner@2.1.6':
resolution: {integrity: sha512-WpiEmi/SxAVED0N/M0kvPZwq/MxMuuz/Y89ut1sTP7syPzpCauGxafOdqkTqiX1ef+N1ZlrtX+v/LwDF/jIgFw==}
'@rivetkit/engine-runner@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd}
version: 2.1.6
@ -3050,10 +3044,6 @@ packages:
resolution: {integrity: sha512-5RC9Ze/wTKqSlJvopdCgr+EfyV93+iiH8Thog0QXrl8PT1unuBNw/jadXNMtwgAxrIaCJL+JLaHQH9w7rqpMDw==}
engines: {node: '>=20'}
'@rivetkit/sqlite-vfs@2.1.6':
resolution: {integrity: sha512-jbCrigzqoygZTYdZu7izaQjr77Q4BFX1HwhW4Mf0UFIaKT72AteH/w4PcktzrKcw4Utmo0zX0C6zNBRKo0IpOA==}
engines: {node: '>=20.0.0'}
'@rivetkit/sqlite-vfs@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd}
version: 2.1.6
@ -3062,26 +3052,15 @@ packages:
'@rivetkit/sqlite@0.1.1':
resolution: {integrity: sha512-NE7ZBy/hQhOrWzMZFjkHX9SoXxf+ILcDvVV+mNbUYPgiy/fsDzlXdK0+JDTGnko5f4Xl6/KVCoCozz9gkwkq8A==}
'@rivetkit/traces@2.1.6':
resolution: {integrity: sha512-wuuGWoWWdUPbqs5u+31YodSUOsYMydaa+/cxZ7I5KaUe26fK0i1E+0ytqC1JGQm6utWeuYp8cLUX3WSEfVKJhQ==}
engines: {node: '>=18.0.0'}
'@rivetkit/traces@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd}
version: 2.1.6
engines: {node: '>=18.0.0'}
'@rivetkit/virtual-websocket@2.0.33':
resolution: {integrity: sha512-sMoHZgBy9WDW76pv+ML3LPgf7TWk5vXdu3ZpPO20j6n+rB3fLacnnmzjt5xD6tZcJ/x5qINyEywGgcxA7MTMuQ==}
'@rivetkit/virtual-websocket@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd}
version: 2.0.33
'@rivetkit/workflow-engine@2.1.6':
resolution: {integrity: sha512-eLVFBbhOlBQKzO5lu032tOo0OEAFFp7uNcGwvB1mBFmYsm7aKBgnJl214IV39a6fRtCL2meVxiMU1GKb006zYw==}
engines: {node: '>=18.0.0'}
'@rivetkit/workflow-engine@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd}
version: 2.1.6
@ -6370,30 +6349,6 @@ packages:
resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==}
engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
rivetkit@2.1.6:
resolution: {integrity: sha512-AFe06CTZoAYWwCltxPp1XNilfOgK53Itvbc/lv0uF+aEwFEAPIZFQPBTrVgt7NGZSuiM2l6/hjMv7yuBZQ71sw==}
engines: {node: '>=22.0.0'}
peerDependencies:
'@hono/node-server': ^1.14.0
'@hono/node-ws': ^1.1.1
drizzle-kit: ^0.31.2
drizzle-orm: ^0.44.2
eventsource: ^4.0.0
ws: ^8.0.0
peerDependenciesMeta:
'@hono/node-server':
optional: true
'@hono/node-ws':
optional: true
drizzle-kit:
optional: true
drizzle-orm:
optional: true
eventsource:
optional: true
ws:
optional: true
rivetkit@https://pkg.pr.new/rivet-dev/rivet/rivetkit@791500a:
resolution: {tarball: https://pkg.pr.new/rivet-dev/rivet/rivetkit@791500a}
version: 2.1.6
@ -9588,25 +9543,10 @@ snapshots:
'@rivetkit/bare-ts@0.6.2': {}
'@rivetkit/engine-runner-protocol@2.1.6':
dependencies:
'@rivetkit/bare-ts': 0.6.2
'@rivetkit/engine-runner-protocol@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
dependencies:
'@rivetkit/bare-ts': 0.6.2
'@rivetkit/engine-runner@2.1.6':
dependencies:
'@rivetkit/engine-runner-protocol': 2.1.6
'@rivetkit/virtual-websocket': 2.0.33
pino: 9.14.0
uuid: 12.0.0
ws: 8.19.0
transitivePeerDependencies:
- bufferutil
- utf-8-validate
'@rivetkit/engine-runner@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
dependencies:
'@rivetkit/engine-runner-protocol': https://pkg.pr.new/rivet-dev/rivet/@rivetkit/engine-runner-protocol@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd
@ -9622,12 +9562,6 @@ snapshots:
'@rivetkit/on-change@6.0.2-rc.1': {}
'@rivetkit/sqlite-vfs@2.1.6':
dependencies:
'@rivetkit/bare-ts': 0.6.2
'@rivetkit/sqlite': 0.1.1
vbare: 0.0.4
'@rivetkit/sqlite-vfs@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/sqlite-vfs@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
dependencies:
'@rivetkit/bare-ts': 0.6.2
@ -9636,13 +9570,6 @@ snapshots:
'@rivetkit/sqlite@0.1.1': {}
'@rivetkit/traces@2.1.6':
dependencies:
'@rivetkit/bare-ts': 0.6.2
cbor-x: 1.6.3
fdb-tuple: 1.0.0
vbare: 0.0.4
'@rivetkit/traces@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/traces@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
dependencies:
'@rivetkit/bare-ts': 0.6.2
@ -9650,18 +9577,8 @@ snapshots:
fdb-tuple: 1.0.0
vbare: 0.0.4
'@rivetkit/virtual-websocket@2.0.33': {}
'@rivetkit/virtual-websocket@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/virtual-websocket@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd': {}
'@rivetkit/workflow-engine@2.1.6':
dependencies:
'@rivetkit/bare-ts': 0.6.2
cbor-x: 1.6.3
fdb-tuple: 1.0.0
pino: 9.14.0
vbare: 0.0.4
'@rivetkit/workflow-engine@https://pkg.pr.new/rivet-dev/rivet/@rivetkit/workflow-engine@791500a6eb11c29133c3cbe14511f3b6ebf9d5bd':
dependencies:
'@rivetkit/bare-ts': 0.6.2
@ -13499,41 +13416,6 @@ snapshots:
reusify@1.1.0: {}
rivetkit@2.1.6(@hono/node-server@1.19.9(hono@4.12.2))(@hono/node-ws@1.3.0(@hono/node-server@1.19.9(hono@4.12.2))(hono@4.12.2))(@standard-schema/spec@1.1.0)(drizzle-kit@0.31.9)(drizzle-orm@0.44.7(@cloudflare/workers-types@4.20260317.1)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.18.0)(better-sqlite3@11.10.0)(bun-types@1.3.10)(kysely@0.28.11)(pg@8.20.0))(ws@8.19.0):
dependencies:
'@hono/standard-validator': 0.1.5(@standard-schema/spec@1.1.0)(hono@4.12.2)
'@hono/zod-openapi': 1.2.2(hono@4.12.2)(zod@4.3.6)
'@rivetkit/bare-ts': 0.6.2
'@rivetkit/engine-runner': 2.1.6
'@rivetkit/fast-json-patch': 3.1.2
'@rivetkit/on-change': 6.0.2-rc.1
'@rivetkit/sqlite': 0.1.1
'@rivetkit/sqlite-vfs': 2.1.6
'@rivetkit/traces': 2.1.6
'@rivetkit/virtual-websocket': 2.0.33
'@rivetkit/workflow-engine': 2.1.6
cbor-x: 1.6.3
get-port: 7.1.0
hono: 4.12.2
invariant: 2.2.4
nanoevents: 9.1.0
p-retry: 6.2.1
pino: 9.14.0
tar: 7.5.7
uuid: 12.0.0
vbare: 0.0.4
zod: 4.3.6
optionalDependencies:
'@hono/node-server': 1.19.9(hono@4.12.2)
'@hono/node-ws': 1.3.0(@hono/node-server@1.19.9(hono@4.12.2))(hono@4.12.2)
drizzle-kit: 0.31.9
drizzle-orm: 0.44.7(@cloudflare/workers-types@4.20260317.1)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.18.0)(better-sqlite3@11.10.0)(bun-types@1.3.10)(kysely@0.28.11)(pg@8.20.0)
ws: 8.19.0
transitivePeerDependencies:
- '@standard-schema/spec'
- bufferutil
- utf-8-validate
rivetkit@https://pkg.pr.new/rivet-dev/rivet/rivetkit@791500a(@e2b/code-interpreter@2.3.3)(@hono/node-server@1.19.9(hono@4.12.2))(@hono/node-ws@1.3.0(@hono/node-server@1.19.9(hono@4.12.2))(hono@4.12.2))(@standard-schema/spec@1.1.0)(dockerode@4.0.9)(drizzle-kit@0.31.9)(drizzle-orm@0.44.7(@cloudflare/workers-types@4.20260317.1)(@opentelemetry/api@1.9.0)(@types/better-sqlite3@7.6.13)(@types/pg@8.18.0)(bun-types@1.3.10)(kysely@0.28.11)(pg@8.20.0))(ws@8.19.0):
dependencies:
'@hono/standard-validator': 0.1.5(@standard-schema/spec@1.1.0)(hono@4.12.2)