Skip to content

fix(ci): platform-portable mcp stdin + abort test; round-2 bug batch#9

Merged
QiaolongLi1201 merged 2 commits into
mainfrom
fix/ci-platform-portability
Jun 13, 2026
Merged

fix(ci): platform-portable mcp stdin + abort test; round-2 bug batch#9
QiaolongLi1201 merged 2 commits into
mainfrom
fix/ci-platform-portability

Conversation

@QiaolongLi1201

Copy link
Copy Markdown
Collaborator

Why

CI on main is red (runs #7/#8) even though local verify is green — because the local gate only runs on macOS, and neither failure reproduces on macOS. This is the real "检测不完备": macOS-only verification cannot catch Linux EPIPE semantics or the absence of /bin/sh on Windows.

Confirmed failures fixed (commit 1, e7af47e)

  • ubuntu-latestmcp-stdin-write-error.spec.mjs crashed the node process with write EPIPE. McpServerConnection never listened for 'error' on the child's stdin; writing to a just-exited MCP server's stdin emits an async error event that, unhandled, escalates to an uncaught exception. macOS silently buffers the write, so the test passed there. Fix: add a stdin 'error' handler (fail in-flight requests + mark closed) and guard notify()'s best-effort write.
  • windows-latestrun-process-abort-cleanup.spec.mjs spawned /bin/sh, which ENOENTs on Windows before the abort timer fires, so the assertion saw a spawn error, not an abort rejection. Fix: spawn a cross-platform sleeper via process.execPath + node -e setTimeout.

The test runner is fail-fast, so each platform died at its first failure and hid everything after it. I swept every test that actually spawns a process: only run-process-abort-cleanup was unguarded; tools-cancel-safety, ssh-end-to-end, background-exec already skip on win32, and the MCP tests use node. New tests sorting after the crash point carry no /bin/sh/spawn hazards.

Round-2 review bug batch (commit 2, c30c74f)

Verified bug fixes (each with a red-before/green-after test) across cli (community-auth token corruption, vim count 0, attachments bounds, print, tui), providers (anthropic tool_use object), tools (browser close timeout, web-fetch SSRF-after-redirect), memory (exponential n-grams), skills (tool-call failure tracking), and contracts (async-task summary, host-adapter undeclared-surface rejection).

Verification

  • npm run verify green locally (macOS).
  • Gate: this PR is merged to main only after CI passes on ubuntu + macos + windows (matrix fail-fast: false, so all three report).

d-robotics and others added 2 commits June 14, 2026 00:08
Two platform-specific CI failures merged to main while the local verify
(macOS-only) stayed green — neither failure mode reproduces on macOS:

- ubuntu: McpServerConnection never listened for 'error' on the child's
  stdin. Writing to a just-exited MCP server's stdin surfaces an async
  EPIPE on the writable stream; with no listener Node escalates it to an
  uncaught exception and kills the process (macOS silently buffers the
  write, so mcp-stdin-write-error.spec.mjs passed there). Add a stdin
  'error' handler that fails in-flight requests and marks the connection
  closed, and guard notify()'s best-effort write against a sync throw.

- windows: run-process-abort-cleanup.spec.mjs spawned '/bin/sh', which
  does not exist on Windows and ENOENTs before the abort timer fires, so
  the assertion saw a spawn error instead of an abort rejection. Spawn a
  long-running child via process.execPath + `node -e setTimeout` instead,
  exercising abort cleanup identically on all three platforms.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A read-only parallel review surfaced a batch of real bugs; each fix ships
with a red-before/green-after test. Flawed candidate findings were dropped
when their test failed `npm run verify` (verify-as-arbiter).

- cli/community-auth: a line-wrapped portal-token paste was joined with '+'
  (token.replace(/\s+/g, '+')), corrupting the JWT; strip whitespace instead.
  Export normalizePortalToken for the regression test.
- cli/input/vim: count-prefix digit guard used /^[1-9]$/, so '0' could never
  be a non-leading count digit (10dd was unreachable); accept /^[0-9]$/ with
  the bare-'0' line-start motion preserved. Add default mode indicator/color.
- cli/attachments: validate index bounds before use.
- cli/print: safe JSON stringify for non-serializable values.
- cli/tui: numeric picker accepts [1-9].
- provider/anthropic: tool_use input must be an object, not a bare value.
- tools/browser-tools: bound the close() wait with a timeout.
- tools/web-fetch: re-check the SSRF waiver after a redirect.
- memory-manager: extractTerms built n-grams in O(2^n); cap the window.
- skill-learner: extractToolCalls now tracks per-call failure for scoring.
- contracts/async-task: consistent summary fallback.
- contracts/host-adapter: reject tools whose side-effect surface is undeclared.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@QiaolongLi1201 QiaolongLi1201 merged commit 3438a92 into main Jun 13, 2026
3 checks passed
@QiaolongLi1201 QiaolongLi1201 deleted the fix/ci-platform-portability branch June 13, 2026 16:25
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.

1 participant