Skip to content

fix(coding-agent): isolate Inspector import crashes#336

Draft
minpeter wants to merge 1 commit into
code-yeongyu:mainfrom
minpeter:fix/inspector-vm-import-crash-main
Draft

fix(coding-agent): isolate Inspector import crashes#336
minpeter wants to merge 1 commit into
code-yeongyu:mainfrom
minpeter:fix/inspector-vm-import-crash-main

Conversation

@minpeter

@minpeter minpeter commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Summary

  • hand an inherited fixed Node Inspector endpoint from the launcher to cli-main
  • keep Inspector VM dynamic-import recovery fail-closed by default
  • allow an explicit startup opt-in only for the exact reported evaluator rejection
  • preserve the existing fatal path for application VM errors, late environment mutation, direct uncaught exceptions, and unrelated failures

This is the current-main replacement for #321. It is one commit directly on main@38bd3a3cf8a47c1201969117b1a82a5af7daac9c; the old draft is conflicting.

Root cause

node inspect/the V8 Inspector protocol evaluates expressions in a VM context without an importModuleDynamically callback. A delayed import:

setTimeout(()=>import('node:fs'),0)

therefore rejects with ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING.

The CLI also has a launcher/child topology. With a fixed NODE_OPTIONS=--inspect=..., the launcher previously claimed the endpoint and cli-main inherited the same option, producing address already in use; the debugger attached to the wrapper instead of the TUI child.

Behavior

Before spawning cli-main, the launcher releases an active Inspector endpoint inherited from Node startup options. The child can bind the same endpoint.

Recovery remains disabled unless the process starts with:

SENPI_RECOVER_INSPECTOR_VM_IMPORT=1 \
NODE_OPTIONS=--inspect=127.0.0.1:9229 \
senpi

The recovery predicate then requires all of:

  • startup opt-in captured when the policy module loads
  • active Inspector endpoint
  • unhandledRejection origin
  • ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING
  • Node's dynamic-import callback frame
  • Inspector <anonymous> timer provenance

Node exposes no non-spoofable Inspector provenance on the global rejection, so the explicit opt-in is required. Later environment mutation cannot enable recovery.

Verification

  • focused regression: 1 file, 5/5 tests passed
  • root topological npm run build: passed
  • coding-agent build: passed
  • root npm run check: passed, including typecheck/browser/web/Neo gates
  • git diff --check: passed
  • changed-file LSP diagnostics: clean

Real CLI QA

Fresh evidence is under local-ignore/qa-evidence/20260725-inspector-vm-import-crash-current-main/ (gitignored).

  • senpi-qa common self-check: 9/9 passed
  • senpi-qa CLI smoke: 7/7 passed
  • senpi-qa tmux TUI smoke: 5/5 passed
  • built real CLI in isolated PTYs, driven through the real V8 Inspector protocol:
    • opt-in: launcher and child sequentially bound the same fixed endpoint, guidance rendered, TUI remained alive
    • default: the identical evaluation emitted the fatal diagnostic and exited 1
    • neither scenario emitted address already in use
  • isolated HOME/config/session paths, offline mode, no provider call, real auth unchanged
  • all owned clients, PTYs, sandboxes, tmux sessions, sockets, and dynamic listeners cleaned

CI state

The security check and all Linux/macOS/Windows terminal jobs passed on both CI runs. The aggregate job remains red on unrelated current-main instability:

  1. Initial run: npm run check timed out in untouched Neo TestAttachOrSpawn_RaceExactlyOneDaemon; the same local root check passed.
  2. One transparent reopened-PR rerun: check and build passed; the full suite completed 4,606 passes and failed only untouched agent-session-compaction.test.ts:1361 (overflowStarts was empty).

This Inspector commit changes neither Neo nor compaction source/tests. Current main@38bd3a3cf also has a red aggregate CI run. No unrelated retry/race or compaction fix is included here.

@minpeter

Copy link
Copy Markdown
Contributor Author

CI note: the first aggregate job failed in untouched Neo test TestAttachOrSpawn_RaceExactlyOneDaemon after a 30s timeout. This branch changes no Neo/check-neo files, local root npm run check passed, and current main itself has a red aggregate CI run. I do not have upstream admin permission to rerun the job directly, so I am reopening this draft once to obtain an independent run without changing the verified Inspector commit.

@minpeter minpeter closed this Jul 24, 2026
@minpeter minpeter reopened this Jul 24, 2026
@minpeter

Copy link
Copy Markdown
Contributor Author

Independent rerun result: all security and cross-platform terminal jobs passed again; aggregate check and build passed, then the full workspace run recorded 4,606 passes and failed only untouched test/suite/agent-session-compaction.test.ts:1361 (overflowStarts was [], expected length 2). This Inspector commit changes no Neo or compaction source/test files, so I am stopping retries and leaving the draft accurately blocked on current-main CI instability.

@minpeter

Copy link
Copy Markdown
Contributor Author

CI follow-up (kept out of this Inspector-only patch):

  • Run 30110663350 failed during npm run check in unchanged Neo test TestAttachOrSpawn_RaceExactlyOneDaemon after the branch's check inputs had passed.
  • Replacement run 30111006014 passed Check, workspace build, GitGuardian, and all three terminal-platform jobs. Its full coding-agent suite completed 4,606 passing tests / 32 skips, then failed one unchanged compaction characterization: agent-session-compaction.test.ts expected two overflow starts and observed zero.
  • The exact compaction assertion reproduces directly at this checkout. This commit changes no Neo, agent-session, compaction, or harness path; its diff remains the audited eight Inspector/CLI/test/doc paths only.
  • Branch-specific verification remains green: Inspector regression 5/5, topological build, coding-agent build, root check, real node inspect opt-in/default QA, and xterm-rendered evidence.

Evidence and command receipts are preserved under the gitignored local-ignore/qa-evidence/20260725-inspector-vm-import-crash-current-main/ directory.

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