You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .agent/contracts/node-runtime.md
+19Lines changed: 19 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -168,6 +168,21 @@ The `__dynamicImport` bridge function SHALL return a Promise that resolves to th
168
168
-**WHEN** user code calls `await import("./nonexistent")`
169
169
-**THEN** the returned Promise MUST reject with an error indicating the module cannot be resolved
170
170
171
+
### Requirement: ESM Top-Level Await Completes Before Execution Finalization
172
+
When sandboxed ESM execution uses top-level `await`, the runtime SHALL keep the entry-module evaluation promise alive until it settles instead of finalizing execution early.
173
+
174
+
#### Scenario: ESM exec waits for entry-module top-level await
175
+
-**WHEN**`exec()` runs an ESM entrypoint whose top-level `await` waits on later async work such as timers or promise-driven startup
176
+
-**THEN** the execution result MUST not be returned until the awaited work finishes and post-`await` statements have run
177
+
178
+
#### Scenario: Static imports wait for transitive top-level await
179
+
-**WHEN** an ESM entrypoint statically imports a dependency that uses top-level `await`
180
+
-**THEN** the entrypoint MUST not continue past the import until the dependency's async module evaluation has completed
181
+
182
+
#### Scenario: Dynamic import waits for imported module top-level await
-**THEN** the import Promise MUST not resolve until the imported module's async evaluation has completed and its namespace is ready
185
+
171
186
### Requirement: Configurable CPU Time Limit for Node Runtime Execution
172
187
The Node runtime MUST support an optional `cpuTimeLimitMs` execution budget for sandboxed code and MUST enforce it as a shared per-execution deadline across runtime calls that execute user-controlled code.
173
188
@@ -179,6 +194,10 @@ The Node runtime MUST support an optional `cpuTimeLimitMs` execution budget for
179
194
-**WHEN** a caller configures `cpuTimeLimitMs` and execution spends time across multiple user-code phases (for example module evaluation plus later active-handle waiting)
180
195
-**THEN** the runtime MUST apply one shared budget across phases rather than resetting timeout per phase
181
196
197
+
#### Scenario: Top-level await timeout uses the shared deadline
198
+
-**WHEN** an ESM entrypoint is still awaiting async module startup and later awaited work exceeds `cpuTimeLimitMs`
199
+
-**THEN** the runtime MUST surface the same timeout failure contract instead of returning a successful result early
200
+
182
201
#### Scenario: Timeout contract is deterministic
183
202
-**WHEN** execution exceeds a configured `cpuTimeLimitMs`
184
203
-**THEN** the runtime MUST return `code``124` and include `CPU time limit exceeded` in stderr
Copy file name to clipboardExpand all lines: docs-internal/friction.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -150,9 +150,9 @@
150
150
- Symptom: compatibility fixtures paid repeated `copy + pnpm install` cost even when fixture inputs were unchanged.
151
151
- Fix: added persistent fixture install cache under `packages/secure-exec/.cache/project-matrix/` keyed by fixture/toolchain/runtime factors with `.ready` marker semantics. Repeated `test:project-matrix` runs now reuse prepared installs.
152
152
153
-
7.TODO: follow up on lazy dynamic-import edge cases in ESM execution.
154
-
- Symptom: `filePath: "/entry.mjs"` with top-level `await import("./mod.mjs")`can log pre-import output and imported-module side effects but miss post-await statements.
7.**[resolved]** ESM top-level await could finalize before async startup completed.
154
+
- Symptom: `filePath: "/entry.mjs"` with top-level `await import("./mod.mjs")`could log pre-import output and imported-module side effects but miss post-await statements.
155
+
-Fix: kept the root module evaluation promise alive across the native V8 session event loop and only finalized exports/results after top-levelawait settled; added runtime-driver regressions for entrypoint, transitive-import, dynamic-import, and timeout coverage.
- Symptom: ESM compile/evaluation failures could be rethrown as generic dynamic-import errors, and fallback namespace construction could throw for primitive/null CommonJS exports.
@@ -180,9 +180,9 @@
180
180
- Symptom: requests like `require('./request')` failed when both `request/` and `request.js` existed.
181
181
- Fix: changed resolver order to match Node behavior: file + extension probes run before directory index/package resolution.
182
182
183
-
6. ESM + top-level await in this runtime path can return early for long async waits.
183
+
6.**[resolved]**ESM + top-level await in this runtime path could return early for long async waits.
184
184
- Symptom: module evaluation could finish before awaited async work (timers/network) completed.
185
-
-Mitigation for example: runner switched to CJS async-IIFE, which `exec()` already awaits reliably.
185
+
-Fix: native V8 ESM execution now defers finalization until the entry-module evaluation promise settles, so long async startup follows Node-style top-level-await semantics instead of requiring a CJS async-IIFE workaround.
186
186
187
187
7.`secure-exec` package build currently fails due to broad pre-existing type errors in bridge/browser files.
188
188
- Symptom: importing `secure-exec` from `dist/` in example loader was not reliable in this workspace state.
0 commit comments