惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

K
Kaspersky official blog
T
Threat Research - Cisco Blogs
N
News and Events Feed by Topic
Hacker News: Ask HN
Hacker News: Ask HN
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
博客园 - 叶小钗
Security Latest
Security Latest
Spread Privacy
Spread Privacy
aimingoo的专栏
aimingoo的专栏
N
News and Events Feed by Topic
Webroot Blog
Webroot Blog
U
Unit 42
Cyberwarzone
Cyberwarzone
小众软件
小众软件
Scott Helme
Scott Helme
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
T
The Blog of Author Tim Ferriss
A
About on SuperTechFans
爱范儿
爱范儿
S
Schneier on Security
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Latest news
Latest news
GbyAI
GbyAI
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
The Register - Security
The Register - Security
WordPress大学
WordPress大学
博客园_首页
Blog — PlanetScale
Blog — PlanetScale
PCI Perspectives
PCI Perspectives
Jina AI
Jina AI
AI
AI
NISL@THU
NISL@THU
I
Intezer
G
GRAHAM CLULEY
B
Blog
S
Secure Thoughts
IT之家
IT之家
宝玉的分享
宝玉的分享
Recent Announcements
Recent Announcements
Y
Y Combinator Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
有赞技术团队
有赞技术团队
V2EX - 技术
V2EX - 技术
Recorded Future
Recorded Future
Hacker News - Newest:
Hacker News - Newest: "LLM"

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4 test: trim doctor command hotspots · openclaw/openclaw@c66f16a test: isolate agent auth and spawn hotspots · openclaw/openclaw@9285935 test: stabilize MCP startup disposal race · openclaw/openclaw@dd9d2eb test: merge browser contract server suites · openclaw/openclaw@5817a76 test: narrow ollama provider discovery setup · openclaw/openclaw@a0d9598 build: declare qa-lab aimock runtime dependency · openclaw/openclaw@24431e5 test: speed up safe-bins exec harness · openclaw/openclaw@ee856ab test: preserve tool helpers in embedded runner mocks · openclaw/openclaw@acd86a0 refactor: move memory embeddings into provider plugins · openclaw/openclaw@77e6e4c test: reuse system-run temp fixtures · openclaw/openclaw@7e9ff0f test: trim hotspot wait overhead · openclaw/openclaw@12a59b0 Check: avoid duplicate boundary prep · openclaw/openclaw@baf11b8 test: reduce hotspot fixture overhead · openclaw/openclaw@3a59edd feat(ui): overhaul settings and slash command UX (#67819) thanks @Bun… · openclaw/openclaw@2cfb660 QA Matrix: exit cleanly on failure · openclaw/openclaw@42805d2 QA Matrix: isolate scenario coverage · openclaw/openclaw@7e659e1 Matrix: refresh crypto bootstrap state · openclaw/openclaw@94081d8 QA Lab: add provider registry · openclaw/openclaw@bb7e982 Matrix: add plugin changelog · openclaw/openclaw@4acab55 test: trim more hotspot overhead · openclaw/openclaw@f485311 test: trim remaining hotspot tests · openclaw/openclaw@6ba8626 test: narrow hotspot mocks · openclaw/openclaw@dbc8179 test: isolate gemini embedding request helpers · openclaw/openclaw@cd330f5 test: trim memory and mcp hotspots · openclaw/openclaw@fd48dfa test: slim provider registry mocks · openclaw/openclaw@2e08c77 test: harden Parallels update smoke · openclaw/openclaw@1a98090 feat: default Anthropic to Opus 4.7 · openclaw/openclaw@628b454 fix: harden node-host shell payload mutability checks · openclaw/openclaw@75c551e fix: land node-host approval binding for native binaries (#66731) (th… · openclaw/openclaw@29919bb CI: add daily schedule to CodeQL workflow (#67645) · openclaw/openclaw@69d25f5 fix(gateway): capture config hash after plugin auto-enable to prevent… · openclaw/openclaw@8c11210 fix: repair sanitized replay tool results before send (#67620) (thank… · openclaw/openclaw@c3c7a99 fix: restrict HTML timeout short-circuit to transient statuses · openclaw/openclaw@de129a6 fix: keep TUI watchdog bound to active run (#67401) (thanks @xantorres) · openclaw/openclaw@3525273 Gateway/skills: dedupe skills prefix-match + drop dead fallback on log · openclaw/openclaw@d7f489f Extensions/lmstudio: back off inference preload after consecutive fai… · openclaw/openclaw@b555214 TUI/streaming: add watchdog that resets the activity indicator after … · openclaw/openclaw@f44ab20 Agents/tool-loop: enable unknown-tool stream guard by default · openclaw/openclaw@36ed367 Gateway/skills: invalidate session skills snapshot on config write · openclaw/openclaw@b23d59a fix: classify HTML provider error pages correctly (#67642) (thanks @s… · openclaw/openclaw@e588e90 fix(skills): remove unused model-usage import (#67641) · openclaw/openclaw@55f05df docs(changelog): credit codex fix superseded PRs · openclaw/openclaw@e485f24 fix(openai-codex): normalize stale transport metadata in resolution a… · openclaw/openclaw@90801ba CI: pin Docker-related GitHub Actions (#67632) · openclaw/openclaw@f697b01 Android: modernize WebView and discovery API usage (#67627) · openclaw/openclaw@44a6e50 fix(deps): bump hono to 4.12.14 and @hono/node-server to 1.19.14 (GHS… · openclaw/openclaw@fbccc18 fix(deps): bump dompurify to 3.4.0 (#67614) · openclaw/openclaw@2c2dc00 CI: add explicit permissions to all workflow jobs (fixes code-scannin… · openclaw/openclaw@01b7516 fix: register bundled TTS providers and route overrides correctly (#6… · openclaw/openclaw@6ea3cdd fix: align host tilde paths with OS home (#62804) (thanks @stainlu) · openclaw/openclaw@ecfaf64 fix: flush creds queue before reconnect socket open (#67464) (thanks … · openclaw/openclaw@405c63f fix: strip standalone <function> tool call tags from visible text (#6… · openclaw/openclaw@78df859 fix(agents): preserve cli session metadata before transcript persist … · openclaw/openclaw@898fd04 docs(changelog): move cli transcript entry · openclaw/openclaw@c1817c6 fix(agents): normalize cli transcript api field · openclaw/openclaw@3a3fae0 docs(changelog): note cli transcript persistence · openclaw/openclaw@6c343f1 fix(agents): persist cli transcript turns · openclaw/openclaw@b8ef507 fix(msteams): harden security-sensitive flows (#65841) · openclaw/openclaw@c56b56e [Dashboard] Fix exec approval modal overflow for long command content… · openclaw/openclaw@053c5b0 Docs: remove QA changelog entry · openclaw/openclaw@7fd5771 QA: fix private runtime source loading (#67428) · openclaw/openclaw@d5933af docs(gateway): correct protocol.md schema path, hello-ok example, aut… · openclaw/openclaw@489404d CI: pin Node 22 runners to 22.18.0 · openclaw/openclaw@4ffa621 models.authStatus: normalize provider ids + tighten env-backed escape… · openclaw/openclaw@f2fdb9d Update CHANGELOG.md · openclaw/openclaw@7694a92 test(parallels): clean up npm update guard jobs · openclaw/openclaw@045ea7b Plugins: prefer scanDir override paths · openclaw/openclaw@b2974da fix(dreaming): default storage.mode to "separate" so phase blocks sto… · openclaw/openclaw@8c392f0 fix(memory-core): skip dreaming transcript ingestion via session stor… · openclaw/openclaw@a1b01f0 fix: dedupe replayed exec.finished node events (#67281) · openclaw/openclaw@5dcf526
fix(qa-lab): resolve Windows taskkill path · openclaw/openclaw@61d1fd1
vincentkoc · 2026-06-21 · via Recent Commits to openclaw:main
Original file line numberDiff line numberDiff line change

@@ -1025,11 +1025,12 @@ describe("buildQaRuntimeEnv", () => {

10251025

runTaskkill,

10261026

);

10271027
1028-

expect(runTaskkill).toHaveBeenNthCalledWith(1, "taskkill", ["/PID", "12345", "/T"], {

1028+

const taskkillPath = path.win32.join("C:\\Windows", "System32", "taskkill.exe");

1029+

expect(runTaskkill).toHaveBeenNthCalledWith(1, taskkillPath, ["/PID", "12345", "/T"], {

10291030

stdio: "ignore",

10301031

windowsHide: true,

10311032

});

1032-

expect(runTaskkill).toHaveBeenNthCalledWith(2, "taskkill", ["/PID", "12345", "/T", "/F"], {

1033+

expect(runTaskkill).toHaveBeenNthCalledWith(2, taskkillPath, ["/PID", "12345", "/T", "/F"], {

10331034

stdio: "ignore",

10341035

windowsHide: true,

10351036

});

Original file line numberDiff line numberDiff line change

@@ -50,6 +50,7 @@ import { stageQaMockAuthProfiles } from "./providers/shared/mock-auth.js";

5050

import { seedQaAgentWorkspace } from "./qa-agent-workspace.js";

5151

import { buildQaGatewayConfig, type QaThinkingLevel } from "./qa-gateway-config.js";

5252

import type { QaTransportAdapter } from "./qa-transport.js";

53+

import { resolveQaWindowsSystem32ExePath } from "./windows-system-tools.js";

5354
5455

export type { QaCliBackendAuthMode } from "./providers/env.js";

5556

const QA_GATEWAY_CHILD_STARTUP_MAX_ATTEMPTS = 5;

@@ -398,19 +399,20 @@ function signalQaGatewayWindowsProcessTree(

398399

signal: NodeJS.Signals,

399400

runTaskkill: QaGatewayTaskkillRunner = spawnSync,

400401

) {

402+

const taskkillPath = resolveQaWindowsSystem32ExePath("taskkill.exe");

401403

const args = ["/PID", String(pid), "/T"];

402404

if (signal === "SIGKILL") {

403405

args.push("/F");

404406

}

405-

const result = runTaskkill("taskkill", args, {

407+

const result = runTaskkill(taskkillPath, args, {

406408

stdio: "ignore",

407409

windowsHide: true,

408410

});

409411

if (!result.error && result.status === 0) {

410412

return true;

411413

}

412414

if (signal !== "SIGKILL") {

413-

const forceResult = runTaskkill("taskkill", [...args, "/F"], {

415+

const forceResult = runTaskkill(taskkillPath, [...args, "/F"], {

414416

stdio: "ignore",

415417

windowsHide: true,

416418

});

Original file line numberDiff line numberDiff line change

@@ -24,6 +24,7 @@ import {

2424

QA_CHANNEL_REQUIRED_PLUGIN_IDS,

2525

} from "./qa-channel-transport.js";

2626

import { buildQaGatewayConfig } from "./qa-gateway-config.js";

27+

import { resolveQaWindowsSystem32ExePath } from "./windows-system-tools.js";

2728
2829

type ModelRow = {

2930

key: string;

@@ -120,10 +121,14 @@ function killProcessTree(pid: number | undefined, signal: NodeJS.Signals) {

120121

}

121122

try {

122123

if (process.platform === "win32") {

123-

const killer = spawn("taskkill", ["/pid", String(pid), "/t", "/f"], {

124-

stdio: "ignore",

125-

windowsHide: true,

126-

});

124+

const killer = spawn(

125+

resolveQaWindowsSystem32ExePath("taskkill.exe"),

126+

["/pid", String(pid), "/t", "/f"],

127+

{

128+

stdio: "ignore",

129+

windowsHide: true,

130+

},

131+

);

127132

killer.once("error", () => {

128133

try {

129134

process.kill(pid, signal);

Original file line numberDiff line numberDiff line change

@@ -213,10 +213,14 @@ describe("qa suite runtime agent process helpers", () => {

213213
214214

await waitForSpawnCount(1);

215215

await timeoutAssertion;

216-

expect(spawnSyncMock).toHaveBeenCalledWith("taskkill", ["/PID", "12345", "/T", "/F"], {

217-

stdio: "ignore",

218-

windowsHide: true,

219-

});

216+

expect(spawnSyncMock).toHaveBeenCalledWith(

217+

path.win32.join("C:\\Windows", "System32", "taskkill.exe"),

218+

["/PID", "12345", "/T", "/F"],

219+

{

220+

stdio: "ignore",

221+

windowsHide: true,

222+

},

223+

);

220224

expect(child.kill).not.toHaveBeenCalled();

221225

} finally {

222226

if (platformDescriptor) {

Original file line numberDiff line numberDiff line change

@@ -19,6 +19,7 @@ import { liveTurnTimeoutMs } from "./suite-runtime-agent-common.js";

1919

import { waitForGatewayHealthy, waitForTransportReady } from "./suite-runtime-gateway.js";

2020

import type { QaDreamingStatus, QaSuiteRuntimeEnv } from "./suite-runtime-types.js";

2121

import { resolveQaGatewayTimeoutWithGraceMs } from "./timer-timeouts.js";

22+

import { resolveQaWindowsSystem32ExePath } from "./windows-system-tools.js";

2223
2324

type QaMemorySearchResult = {

2425

results?: Array<{ snippet?: string; text?: string; path?: string }>;

@@ -209,10 +210,14 @@ function signalQaCliProcessTree(

209210

) {

210211

if (process.platform === "win32") {

211212

if (typeof child.pid === "number") {

212-

const result = spawnSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], {

213-

stdio: "ignore",

214-

windowsHide: true,

215-

});

213+

const result = spawnSync(

214+

resolveQaWindowsSystem32ExePath("taskkill.exe"),

215+

["/PID", String(child.pid), "/T", "/F"],

216+

{

217+

stdio: "ignore",

218+

windowsHide: true,

219+

},

220+

);

216221

if (!result.error && result.status === 0) {

217222

return;

218223

}

Original file line numberDiff line numberDiff line change

@@ -443,11 +443,12 @@ describe("qa test file scenario runner", () => {

443443

runTaskkill,

444444

),

445445

).toBe(true);

446-

expect(runTaskkill).toHaveBeenNthCalledWith(1, "taskkill", ["/pid", "12345", "/T"], {

446+

const taskkillPath = path.win32.join("C:\\Windows", "System32", "taskkill.exe");

447+

expect(runTaskkill).toHaveBeenNthCalledWith(1, taskkillPath, ["/pid", "12345", "/T"], {

447448

stdio: "ignore",

448449

windowsHide: true,

449450

});

450-

expect(runTaskkill).toHaveBeenNthCalledWith(2, "taskkill", ["/pid", "12345", "/T", "/F"], {

451+

expect(runTaskkill).toHaveBeenNthCalledWith(2, taskkillPath, ["/pid", "12345", "/T", "/F"], {

451452

stdio: "ignore",

452453

windowsHide: true,

453454

});

Original file line numberDiff line numberDiff line change

@@ -21,6 +21,7 @@ import type { QaProviderMode } from "./providers/index.js";

2121

import type { QaSeedScenarioWithSource } from "./scenario-catalog.js";

2222

import type { QaScorecardEvidenceMode } from "./scorecard-taxonomy.js";

2323

import { shellQuote } from "./shell-quote.js";

24+

import { resolveQaWindowsSystem32ExePath } from "./windows-system-tools.js";

2425
2526

export type QaTestFileScenario = QaSeedScenarioWithSource & {

2627

execution: Extract<

@@ -196,19 +197,20 @@ function killQaScenarioWindowsProcessTree(

196197

if (pid === undefined) {

197198

return false;

198199

}

200+

const taskkillPath = resolveQaWindowsSystem32ExePath("taskkill.exe");

199201

const args = ["/pid", String(pid), "/T"];

200202

if (signal === "SIGKILL") {

201203

args.push("/F");

202204

}

203-

const result = runTaskkill("taskkill", args, {

205+

const result = runTaskkill(taskkillPath, args, {

204206

stdio: "ignore",

205207

windowsHide: true,

206208

});

207209

if (!result.error && result.status === 0) {

208210

return true;

209211

}

210212

if (signal !== "SIGKILL") {

211-

const forceResult = runTaskkill("taskkill", [...args, "/F"], {

213+

const forceResult = runTaskkill(taskkillPath, [...args, "/F"], {

212214

stdio: "ignore",

213215

windowsHide: true,

214216

});

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,30 @@

1+

// Qa Lab tests cover Windows system tool path resolution.

2+

import { describe, expect, it } from "vitest";

3+

import {

4+

resolveQaWindowsSystem32ExePath,

5+

resolveQaWindowsSystemRoot,

6+

} from "./windows-system-tools.js";

7+
8+

describe("qa-lab windows system tools", () => {

9+

it("resolves System32 executables from a trusted SystemRoot", () => {

10+

expect(resolveQaWindowsSystemRoot({ SystemRoot: "D:\\Windows\\" })).toBe("D:\\Windows");

11+

expect(resolveQaWindowsSystem32ExePath("taskkill.exe", { SystemRoot: "D:\\Windows\\" })).toBe(

12+

"D:\\Windows\\System32\\taskkill.exe",

13+

);

14+

});

15+
16+

it("falls back to the default Windows root when env roots are unsafe", () => {

17+

expect(resolveQaWindowsSystem32ExePath("taskkill.exe", { SystemRoot: "C:\\tmp;C:\\bad" })).toBe(

18+

"C:\\Windows\\System32\\taskkill.exe",

19+

);

20+

});

21+
22+

it("rejects non-basename System32 executable names", () => {

23+

expect(() => resolveQaWindowsSystem32ExePath("..\\taskkill.exe")).toThrow(

24+

"Invalid Windows System32 executable name",

25+

);

26+

expect(() => resolveQaWindowsSystem32ExePath("taskkill")).toThrow(

27+

"Invalid Windows System32 executable name",

28+

);

29+

});

30+

});

Original file line numberDiff line numberDiff line change

@@ -0,0 +1,62 @@

1+

// Qa Lab resolves Windows system tools without trusting PATH.

2+

import path from "node:path";

3+
4+

const DEFAULT_WINDOWS_SYSTEM_ROOT = "C:\\Windows";

5+
6+

function getEnvValueCaseInsensitive(

7+

env: Record<string, string | undefined>,

8+

expectedKey: string,

9+

): string | undefined {

10+

const direct = env[expectedKey];

11+

if (direct !== undefined) {

12+

return direct;

13+

}

14+

const expected = expectedKey.toUpperCase();

15+

const actualKey = Object.keys(env).find((key) => key.toUpperCase() === expected);

16+

return actualKey ? env[actualKey] : undefined;

17+

}

18+
19+

function normalizeWindowsSystemRoot(raw: string | undefined): string | null {

20+

const trimmed = raw?.trim();

21+

if (

22+

!trimmed ||

23+

trimmed.includes("\0") ||

24+

trimmed.includes("\r") ||

25+

trimmed.includes("\n") ||

26+

trimmed.includes(";")

27+

) {

28+

return null;

29+

}

30+

const normalized = path.win32.normalize(trimmed);

31+

if (!path.win32.isAbsolute(normalized) || normalized.startsWith("\\\\")) {

32+

return null;

33+

}

34+

const parsed = path.win32.parse(normalized);

35+

if (!/^[A-Za-z]:\\$/u.test(parsed.root) || normalized.length <= parsed.root.length) {

36+

return null;

37+

}

38+

return normalized.replace(/[\\/]+$/u, "");

39+

}

40+
41+

export function resolveQaWindowsSystemRoot(

42+

env: Record<string, string | undefined> = process.env,

43+

): string {

44+

return (

45+

normalizeWindowsSystemRoot(getEnvValueCaseInsensitive(env, "SystemRoot")) ??

46+

normalizeWindowsSystemRoot(getEnvValueCaseInsensitive(env, "WINDIR")) ??

47+

DEFAULT_WINDOWS_SYSTEM_ROOT

48+

);

49+

}

50+
51+

export function resolveQaWindowsSystem32ExePath(

52+

executableName: string,

53+

env: Record<string, string | undefined> = process.env,

54+

): string {

55+

if (

56+

path.win32.basename(executableName) !== executableName ||

57+

!/^[A-Za-z0-9_.-]+\.exe$/u.test(executableName)

58+

) {

59+

throw new Error(`Invalid Windows System32 executable name: ${executableName}`);

60+

}

61+

return path.win32.join(resolveQaWindowsSystemRoot(env), "System32", executableName);

62+

}