Skip to content

feat(stdio): Phase 7 - Stream backpressure and memory caps#76

Open
shleder wants to merge 1 commit into
mainfrom
feat/phase7-stdio-backpressure
Open

feat(stdio): Phase 7 - Stream backpressure and memory caps#76
shleder wants to merge 1 commit into
mainfrom
feat/phase7-stdio-backpressure

Conversation

@shleder

@shleder shleder commented May 22, 2026

Copy link
Copy Markdown
Owner

This pull request was created by @kiro-agent on behalf of @shleder 👻

Comment with /kiro fix to address specific feedback or /kiro all to address everything.
Learn about Kiro autonomous agent


Summary

Implements Phase 7 (Stdio Transport Stability) from the audit plan. Hardens src/stdio/proxy.ts against unbounded Node.js stream buffering and buffer overflow attacks.

Changes

1. Await Drain on Stdin

  • Honors the boolean returned by targetProcess.stdin.write().
  • When false, pauses clientInterface readline and registers a one-time 'drain' listener on target stdin to resume.
  • Preserves the existing STDIO_TARGET_BACKPRESSURE audit log entry.

2. Await Drain on Stdout

  • writeRawJson() now checks the return value of output.write().
  • When backpressure is detected, pauses targetInterface (response readline) and awaits the 'drain' event before processing further target output.

3. Memory Caps (Throughput Limiter)

  • Implements a sliding-window byte counter per direction (stdin/stdout).
  • Default cap: 50 MB/s, configurable via MCP_STDIO_MAX_THROUGHPUT_BPS environment variable.
  • When the cap is exceeded within a 1-second window, the respective readline is paused until the window resets.

4. Clean Maps (Race Condition Prevention)

  • failAllPending() now snapshots all entries, calls pendingRequests.clear() atomically, then iterates the snapshot to clear timeouts and write error responses. This prevents race conditions where new entries could be added during iteration and then incorrectly deleted.
  • clearPendingRequest() now uses a delete-first pattern: deletes from map immediately, then clears the timeout if the entry existed.

Validation

  • Ran tsc --noEmit: no new errors introduced by this change (all remaining errors are pre-existing missing @types/node due to absent node_modules).
  • No Tauri build or integration test attempted per constraints (cloud IDE environment).

Limitations

  • Full npm run typecheck cannot pass cleanly without npm install (blocked by "Repository access only" network mode). The errors specific to this file were verified to be exclusively pre-existing infrastructure issues (missing type declarations for Node.js globals).

- Await drain on stdin: pause clientInterface readline when
  targetProcess.stdin.write() returns false, resume on drain event
- Await drain on stdout: pause targetInterface when output.write()
  returns false, resume on drain event via waitForOutputDrain()
- Memory caps: add sliding-window throughput limiter (50MB/s default,
  configurable via MCP_STDIO_MAX_THROUGHPUT_BPS) that pauses the
  respective readline when exceeded
- Clean maps: failAllPending() now snapshots entries and calls
  pendingRequests.clear() atomically before iterating; clearPendingRequest()
  uses delete-first pattern to prevent race conditions during teardown

Co-authored-by: Shleder <230892287+shleder@users.noreply.github.com>
@vercel

vercel Bot commented May 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
toolwall Ready Ready Preview, Comment May 22, 2026 6:47pm
toolwall-cvep Ready Ready Preview, Comment May 22, 2026 6:47pm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants