Sfoglia il codice sorgente

docs(code-runtime-python): drop the orphan receive-cap JSDoc and correct the frame comments

The review's three stale-comment items in index.ts: the orphan JSDoc above
FRAME_PARSE_CAP_BYTES (left over from the deleted receive ceiling), the
pre-join comment's change narration and its reference to a no-longer-existing
higher ceiling, and the first-frame comment's mention of a per-line cap check
that no longer exists. Test comments for the pythonBin and sealing-threshold
cases are weakened to their observable claims (both orders reject an over-cap
frame; the pythonBin case pins the contract, not a worker-exit distinction).
Chinesezjc 2 settimane fa
parent
commit
7fbf370d87

+ 12 - 26
packages/code-runtime/code-runtime-python/src/index.ts

@@ -191,19 +191,6 @@ function materializePyScripts(): string {
   return join(dir, 'bootstrap.py')
 }
 
-/**
- * The fd-3 receive cap for one unframed line: a pure host-memory-safety
- * bound, NOT an output budget. Binding `call` frames legitimately carry large
- * arguments (the seam puts no byte cap on binding traffic), so the cap
- * must sit far above any plausible frame while still stopping a hostile
- * newline-free flood from growing the host accumulator without bound — the
- * child's RLIMIT_AS bounds the child, not the host string. 64 MiB mirrors
- * the order of the worker backend's default outer-output cap while keeping
- * decode amplification (see FRAME_PARSE_CAP_BYTES) a bounded factor of the
- * wire bytes; completion values have their own `maxValueBytes` check at the
- * `done` handler, deliberately decoupled from this. Not a config knob because
- * it is an internal framing invariant, not a deployment choice.
- */
 /**
  * A frame's RAW length is capped before JSON.parse: the 64 MiB fd-3 frame
  * parse cap bounds the bytes, not the decoded structure, and a compact wide
@@ -1322,17 +1309,16 @@ export class PythonCodeRuntime extends CodeRuntime {
         // pipe read of the 64 MiB cap, orders of magnitude past the 32/64 KiB
         // defaults.
         //
-        // The cap used HERE is FRAME_PARSE_CAP_BYTES, not the old 256 MiB
-        // wire ceiling, and ONLY when the held bytes are still a single unframed
-        // line (this chunk carries no newline, and earlier newline-bearing
-        // chunks were joined immediately): a frame between 64 MiB and the
-        // ceiling would otherwise be fully `Buffer.concat`-ed (a second copy
-        // of its bytes) and only then dropped in the line loop — the
-        // peak-memory doubling this pre-concat check exists to prevent.
-        // Dropping the oversized unframed buffer before the join keeps the
-        // peak at one copy of the wire bytes. When this chunk DOES carry a
-        // newline the buffer holds several frames, so the FIRST-FRAME check
-        // below (not this counter, which charges them all) decides.
+        // The cap is enforced ONLY when the held bytes are still a single
+        // unframed line (this chunk carries no newline, and earlier
+        // newline-bearing chunks were joined immediately): a frame past the cap
+        // would otherwise be fully `Buffer.concat`-ed (a second copy of its
+        // bytes) and only then dropped in the line loop — the peak-memory
+        // doubling this pre-concat check exists to prevent. Dropping the
+        // oversized unframed buffer before the join keeps the peak at one copy
+        // of the wire bytes. When this chunk DOES carry a newline the buffer
+        // holds several frames, so the FIRST-FRAME check below (not this
+        // counter, which charges them all) decides.
         if (pendingBytes > FRAME_PARSE_CAP_BYTES && !chunk.includes(0x0a)) {
           pendingChunks = []
           sealedBlocks = []
@@ -1376,8 +1362,8 @@ export class PythonCodeRuntime extends CodeRuntime {
           // serve here — it charges the whole buffer, which legitimately
           // holds several frames each within the cap. A first frame past the
           // cap is dropped before the join (one copy of its wire bytes);
-          // later frames in the same buffer are handled by the per-line check
-          // in the loop below.
+          // later frames in the same buffer are handled line by line in the
+          // loop below.
           let firstFrameLen = 0
           let sawNewline = false
           // Sealed blocks hold newline-free prefixes only (see the sealing

+ 12 - 9
packages/code-runtime/code-runtime-python/tests/runtime.spec.ts

@@ -143,10 +143,12 @@ describe('PythonCodeRuntime — seam descriptors and misuse', () => {
 
   it('skips relative PATH entries when resolving a basename pythonBin', async () => {
     // resolvePythonBin must return an absolute path: a RELATIVE PATH entry
-    // ('.' here) would otherwise resolve the basename against the host CWD —
-    // spawn() then tries './python3' from the test process's directory, where
-    // no interpreter exists, surfacing an ENOENT worker-exit instead of a
-    // normal run. The relative entry is skipped and the absolute entry used.
+    // ('.' here) would otherwise resolve the basename against the host CWD.
+    // This run's CWD holds no executable named python3, so both the relative
+    // skip and the accessSync-miss fall through to the absolute entry — the
+    // case pins the contract (absolute candidate wins over a relative PATH
+    // prefix), not a worker-exit distinction, which would need an executable
+    // named python3 in the test CWD.
     const cp = await import('node:child_process')
     const nodePath = await import('node:path')
     const pythonDir = nodePath.dirname(cp.execFileSync('which', ['python3'], { encoding: 'utf8' }).trim())
@@ -4925,12 +4927,13 @@ describe('PythonCodeRuntime — hostile peer', () => {
   it('rejects an oversized first frame that lands on the sealing threshold with a newline', async () => {
     // The fragment-count seal runs only on newline-free chunks (the ELSE half
     // of the newline branch), so a chunk that carries the first newline always
-    // reaches the join and its first-frame check. Fail-before: sealing that
-    // chunk into a block would empty pendingChunks, leave sawNewline false,
-    // skip the first-frame check, and join the oversized first frame whole.
+    // reaches the join and its first-frame check; sealing it into a block
+    // would empty pendingChunks, leave sawNewline false, and skip that check.
     // Whether the pipe delivers exactly 1024 chunks is timing-dependent, but
-    // the oversized first frame (63.9 MiB of A's + 12288 more before the
-    // newline) exceeds FRAME_PARSE_CAP_BYTES no matter how it arrives.
+    // the oversized first frame (63.9 MiB of A's + 12289 more before the
+    // newline) exceeds FRAME_PARSE_CAP_BYTES no matter how it arrives — the
+    // case pins the worker-exit settlement, not a pre/post copy-count
+    // distinction (both orders reject an over-cap frame).
     const { runtime } = await setup({ maxWallMs: 60_000, addressSpaceMb: 2048 })
     const result = await runtime.run({
       program: [