Repository navigation
Conversation
The Windows process snapshot only carries Toolhelp exe basenames, so a node- or python-hosted agent shows up as `node.exe` and neither the process-name layer nor the ancestor residue can identify it. Read the real command line for the ancestor chain only, via NtQueryInformationProcess(ProcessCommandLineInformation), and rewrite those rows into the unix snapshot's `argv0 args...` shape so the downstream layers run unchanged. - Ancestors only, at most 15 hops, 50ms budget; the current process's own argv is left out so its flag values can't match agent substrings. - Stops at the first parent created after its descendant (stale Toolhelp ppid after pid reuse). - Any failure (access denied, protected process, pre-8.1) keeps the Toolhelp basename, i.e. the previous behavior. - Parsing (CommandLineToArgvW rules), argv normalization and the kernel-buffer bounds checks are pure and unit-tested on every platform. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
codyde
force-pushed
the
cody/windows-ancestor-cmdline
branch
from
October 16, 2026 18:19
e882064 to
2101f6f
Compare
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
On Windows the CLI's process snapshot carries only Toolhelp exe basenames (
node.exe,python.exe). A node- or python-hosted agent (node.exe …\node_modules\@anthropic-ai\claude-code\cli.js) therefore matches nothing incaller_from_process_name, and theagent_unknown:<kind>:<residue>discovery segment never fires on Windows.Warehouse data (
fct_agentic_events, Oct 8–14, bot farm excluded):agent_unknown:nodeusers are on Windows.agent_unknown:node/:python/:vscode:language_server_windows_x64buckets that this can identify or catalog.What changes
build_windows_snapshotnow callsenrich_ancestor_command_lines, which reads the real command line for each ancestor of the current process. It rewrites those rows into the same lowercasedargv0 args...shapepsgives on unix, so the identification, parent-kind and residue layers run unchanged:NtQueryInformationProcess(ProcessCommandLineInformation)(Windows 8.1+) on aPROCESS_QUERY_LIMITED_INFORMATIONhandle. The kernel copies the string into our buffer, so there's noPROCESS_VM_READ/ PEB read and no WOW64 32/64-bit layout handling.parse_windows_command_linefollows theCommandLineToArgvWrules, so quoted paths with spaces stay whole.windows_command_from_argv\into/, soscript_residue'snode_modules/package extraction works;ps, so an arg with a space splits again and the residue's split-path guard aborts instead of emitting part of a directory name.parent_boot_timenow shares the newprocess_creation_timehelper.Safety and performance bounds
OpenProcessplus two queries.railway …command, and flag values could match agent substrings.UNICODE_STRINGheader is bounds-checked against our own allocation before decoding (decode_command_line_buffer). Buffer sizes are capped at the 32,767-unit command-line maximum, with one resize retry.STATUS_INVALID_INFO_CLASSon pre-8.1, and the budget running out.NtQueryInformationProcessis declared againstntdlldirectly;winapi0.3.9 doesn't bind it.Known shared hazard (not new to unix): with args visible, the substring arms of
caller_from_process_name(cody,copilot,gemini, …) can match words in paths, such as a user directory. Unix has had this since it reads full argv. This PR brings Windows to parity rather than fixing it.Testing
2n/2n+1backslash rules,""), argv-to-command normalization including a Claude Codenode_modulespath, residue recovery of an unknown npm package, the spaces-in-path abort, and buffer bounds checks.cargo fmt --checkpasses.cargo clippy --all-targetsreports no new warnings.cargo test: 1,842 passed. 2cloud_agentPython bootstrap tests failed withAddress already in use, because other local worktrees were running the suite at the same time. They don't touch telemetry.cargo clippy --target x86_64-pc-windows-gnu -- -D warnings. It passes.Not verified (why this is a draft)
NtQueryInformationProcessresults, linkingntdllon MSVC and GNU (cargo checkdoesn't link), elevated and other-user parent behavior, and the observed caller from Claude Code / Codex / npm-installed agents running undernode.exe.railway whoamifrom Claude Code, from a Windows npm-installed agent, and from a plain PowerShell, and compare the caller sent in telemetry before and after.🤖 Generated with Claude Code