{"record":{"id":"10a1e7323824fbee","repo":"stablyai/orca","slug":"owned-window-manager-processes-survived-cleanup","errorCode":null,"errorMessage":"Owned window-manager processes survived cleanup: ${evidence.windowManagerGroupAfterCleanup.join('; ')}","messagePattern":"Owned window-manager processes survived cleanup: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"config/scripts/run-terminal-ibus-hangul-e2e.mjs","lineNumber":238,"sourceCode":"      path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-ibus.log')\n    )\n    copyFileSync(\n      windowManagerLogPath,\n      path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-xfwm4.log')\n    )\n    writeFileSync(\n      path.join(projectDir, 'test-results', 'terminal-ibus-hangul-native-processes.json'),\n      `${JSON.stringify(evidence, null, 2)}\\n`\n    )\n  }\n\n  if (evidence.ibusGroupAfterCleanup.length > 0) {\n    throw new Error(\n      `Owned IBus processes survived cleanup: ${evidence.ibusGroupAfterCleanup.join('; ')}`\n    )\n  }\n  if (evidence.windowManagerGroupAfterCleanup.length > 0) {\n    throw new Error(\n      `Owned window-manager processes survived cleanup: ${evidence.windowManagerGroupAfterCleanup.join('; ')}`\n    )\n  }\n  return testExitCode\n}\n\nasync function runOuter() {\n  if (process.platform !== 'linux') {\n    throw new Error('The native IBus Hangul E2E runner requires Linux/X11')\n  }\n\n  const evidenceDir = mkdtempSync(path.join(os.tmpdir(), 'orca-terminal-ime-e2e-'))\n  const runtimeDir = path.join(evidenceDir, 'runtime')\n  mkdirSync(runtimeDir, { mode: 0o700 })\n  mkdirSync(path.join(evidenceDir, 'config'))\n  mkdirSync(path.join(evidenceDir, 'cache'))\n  console.error(`[terminal-ime] evidence directory: ${evidenceDir}`)\n","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/config/scripts/run-terminal-ibus-hangul-e2e.mjs#L220-L256","documentation":"Same invariant as the IBus check but for the xfwm4 process group: after the run, stopOwnedProcessGroup(windowManagerProcess.pid) must return an empty list. Survivors mean the window manager (or a compositor child) escaped cleanup and would leak into the next test's X session.","triggerScenarios":"xfwm4 or a compositor/helper it forked survived the group-kill because it was reparented, ignored SIGTERM, or was re-activated by the X server.","commonSituations":"xfwm4 spawned a compositor process outside its group; the WM ignored the signal under load; the X server restarted the WM via its session manager; cgroup/PID-namespace isolation blocked the kill.","solutions":["Read the processes.json evidence file for the surviving WM PIDs.","Start xfwm4 with --compositor=off (already set) and confirm no compositor child is spawned.","Run the whole X11 session under xvfb-run inside a PID namespace so the group is reaped on session exit.","Escalate stopOwnedProcessGroup to SIGKILL and re-verify for the WM group specifically."],"exampleFix":"// before\n// xfwm4 child compositor survives group kill\n// after\n// run the harness under a PID namespace\nunshare -p --fork --mount-proc pnpm run test:e2e:terminal-ibus-hangul-native","handlingStrategy":"validation","validationCode":"const wmSurvivors = await stopOwnedProcessGroup(windowManagerProcess.pid)\nif (wmSurvivors.length > 0) {\n  console.error('WM survivors:', wmSurvivors)\n}","typeGuard":null,"tryCatchPattern":"try { /* test body */ }\nfinally {\n  const wmSurvivors = await stopOwnedProcessGroup(windowManagerProcess.pid)\n  if (wmSurvivors.length) throw new Error(`Owned window-manager processes survived cleanup: ${wmSurvivors.join('; ')}`)\n}","preventionTips":["Start xfwm4 with --compositor=off to avoid extra compositor children.","Reap inside a PID namespace for deterministic cleanup.","Make stopOwnedProcessGroup escalate to SIGKILL and re-check."],"tags":["x11","window-manager","process-cleanup","process-group","leak","linux","e2e"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}