Summary
A repository-wide Deep Security Scan on Windows terminates during deterministic setup, before discovery, because line 1 of the generated in_scope_files.txt is rejected as an unsafe repository-relative path.
The original staged inventory was removed by normal failed-setup cleanup before it could be inspected. A bounded reproduction using the same installed plugin helper and validator produces the identical error: ripgrep emits a Windows-native backslash-separated row, while the downstream Deep Scan validator requires POSIX-style repository-relative paths.
Environment
- Windows 11 Home 25H2, build 26200.8875, x64
- Codex Desktop 26.803.5235.0
- Codex Security plugin 0.1.18
- Bundled Python helper 3.12.13
- ripgrep 15.2.0
- Scan mode: repository-wide Deep Security Scan
- Public target:
woodpecker-ci/woodpecker at e1c0b37db93cdaf183042fa82890638d713f4ecb
- Target worktree: clean
- Workspace permissions: managed profile
The failure manifest records deterministic setup as incomplete and terminally failed, with zero discoveries, zero dispatched workers, and zero worker executions.
Steps to reproduce
On Windows, create a disposable Git repository containing one nested file:
Run the helper bundled with Codex Security plugin 0.1.18:
<python> -I -B <plugin-root>/scripts/generate_in_scope_files.py --repo <temporary-repository> --scope . --out <temporary-output>
The helper exits successfully but writes:
Passing that row through the bundled MCP runtime's actual parseInScopePaths / validateRepositoryPath logic reproduces the failure before any discovery worker starts.
The original product failure occurred while starting a repository-wide Deep Security Scan against woodpecker-ci/woodpecker at e1c0b37db93cdaf183042fa82890638d713f4ecb.
Actual behavior
in_scope_files.txt:1 must be a safe repository-relative path.
Discovery does not start, and the logical scan becomes terminally failed during deterministic setup.
Expected behavior
Codex Security should generate and consume one canonical repository-relative inventory representation on Windows, then begin discovery successfully.
Evidence
Affected plugin 0.1.18, disposable one-file repository:
generator exit: 0
first row: .\nested\example.txt
drive-letter prefix: no
absolute path: no
traversal: no
leading/trailing whitespace: no
control characters: no
validator result: rejected
validator exit: 2
validator error: in_scope_files.txt:1 must be a safe repository-relative path.
Tested correction using ripgrep's output-separator option:
rg --files --hidden --glob '!.git/**' --path-separator / -- .
ripgrep exit: 0
first row: ./nested/example.txt
same validator result: accepted
same validator exit: 0
Current public main at 0facad0b2bda57d845ae22f8b87584ddd716ffba produces the same .\nested\example.txt row and the same validator rejection. The latest public package release, @openai/codex-security@0.1.7 (bundled plugin 0.1.15), has Git blobs identical to current main for both the generator and bundled MCP runtime, so it is affected as well.
Root cause analysis
The affected 0.1.18 generator invokes ripgrep as:
rg --files --hidden --glob !.git/** -- .
Current main adds --no-ignore but likewise does not set the output path separator. See generate_in_scope_files.py on current main.
ripgrep 15.2.0 documents that printed paths default to the platform separator: / on Unix and \ on Windows. The generator preserves and sorts ripgrep's raw output bytes.
The bundled MCP runtime strips repeated leading ./ prefixes and then rejects empty paths, NULs, backslashes, leading /, drive-letter prefixes, dot/traversal components, and empty path components. Therefore the generator emits .\nested\example.txt on Windows, the parser does not remove its .\ prefix, and validation rejects the backslashes.
This is a generator/consumer contract mismatch in deterministic Deep Scan setup, not a target-repository problem.
Suggested correction
The tested minimal correction is to make the generator invoke ripgrep with --path-separator /. In the disposable Windows repository this changed the row to ./nested/example.txt, which the existing parser normalized and the same validator accepted.
This is preferable to an unconditional string replacement: POSIX permits literal backslash and colon characters in filenames, and related inventory work explicitly preserves those names. A correction should change separator rendering without rewriting filename characters.
Please add a native Windows regression that runs the real generator and the Deep Scan setup validator on at least one nested path. It should verify that the generated inventory:
- is repository-relative;
- uses the canonical separator expected by downstream validation;
- has no drive-letter prefix;
- has no traversal;
- remains compatible with legitimate filenames on supported platforms; and
- works through Deep Scan deterministic setup, not only Standard Scan.
The current generator test checks only that an ignored tracked filename appears as a substring, so it does not detect a leading .\ or Windows separators: runtime.test.ts.
Related work
- PR #267 merged the shared
generate_in_scope_files.py helper and unified Deep Scan with Standard Scan phases. It introduced the affected Deep Scan generator path but did not force canonical separators or assert them on native Windows. It is the relevant causal change, not a fix.
- PR #88 is open authoritative-inventory work for Standard Scan. It does not modify
generate_in_scope_files.py, does not exercise this Deep Scan setup path, and does not fix the observed failure. Its POSIX filename-preservation requirements are relevant to choosing a safe correction.
- PR #85 addressed case-insensitive native Windows scan/artifact path containment. It does not address separators inside repository-relative inventory rows.
- Issue #283 reports a different Windows Deep Scan failure involving locale-dependent subprocess decoding after workers emit output. This setup-time inventory validation failure is not a duplicate.
No open or closed issue, comment, PR, or open PR file list found an exact report or pending fix for this failure.
Privacy
- The failure occurred before discovery.
- No private source, credentials, findings, or complete scan artifacts are included.
- The complete inventory and coordinator manifest are not included.
- Local absolute paths and usernames were redacted.
Summary
A repository-wide Deep Security Scan on Windows terminates during deterministic setup, before discovery, because line 1 of the generated
in_scope_files.txtis rejected as an unsafe repository-relative path.The original staged inventory was removed by normal failed-setup cleanup before it could be inspected. A bounded reproduction using the same installed plugin helper and validator produces the identical error: ripgrep emits a Windows-native backslash-separated row, while the downstream Deep Scan validator requires POSIX-style repository-relative paths.
Environment
woodpecker-ci/woodpeckerate1c0b37db93cdaf183042fa82890638d713f4ecbThe failure manifest records deterministic setup as incomplete and terminally failed, with zero discoveries, zero dispatched workers, and zero worker executions.
Steps to reproduce
On Windows, create a disposable Git repository containing one nested file:
Run the helper bundled with Codex Security plugin 0.1.18:
The helper exits successfully but writes:
Passing that row through the bundled MCP runtime's actual
parseInScopePaths/validateRepositoryPathlogic reproduces the failure before any discovery worker starts.The original product failure occurred while starting a repository-wide Deep Security Scan against
woodpecker-ci/woodpeckerate1c0b37db93cdaf183042fa82890638d713f4ecb.Actual behavior
Discovery does not start, and the logical scan becomes terminally failed during deterministic setup.
Expected behavior
Codex Security should generate and consume one canonical repository-relative inventory representation on Windows, then begin discovery successfully.
Evidence
Affected plugin 0.1.18, disposable one-file repository:
Tested correction using ripgrep's output-separator option:
Current public
mainat0facad0b2bda57d845ae22f8b87584ddd716ffbaproduces the same.\nested\example.txtrow and the same validator rejection. The latest public package release,@openai/codex-security@0.1.7(bundled plugin 0.1.15), has Git blobs identical to current main for both the generator and bundled MCP runtime, so it is affected as well.Root cause analysis
The affected 0.1.18 generator invokes ripgrep as:
Current main adds
--no-ignorebut likewise does not set the output path separator. Seegenerate_in_scope_files.pyon current main.ripgrep 15.2.0 documents that printed paths default to the platform separator:
/on Unix and\on Windows. The generator preserves and sorts ripgrep's raw output bytes.The bundled MCP runtime strips repeated leading
./prefixes and then rejects empty paths, NULs, backslashes, leading/, drive-letter prefixes, dot/traversal components, and empty path components. Therefore the generator emits.\nested\example.txton Windows, the parser does not remove its.\prefix, and validation rejects the backslashes.This is a generator/consumer contract mismatch in deterministic Deep Scan setup, not a target-repository problem.
Suggested correction
The tested minimal correction is to make the generator invoke ripgrep with
--path-separator /. In the disposable Windows repository this changed the row to./nested/example.txt, which the existing parser normalized and the same validator accepted.This is preferable to an unconditional string replacement: POSIX permits literal backslash and colon characters in filenames, and related inventory work explicitly preserves those names. A correction should change separator rendering without rewriting filename characters.
Please add a native Windows regression that runs the real generator and the Deep Scan setup validator on at least one nested path. It should verify that the generated inventory:
The current generator test checks only that an ignored tracked filename appears as a substring, so it does not detect a leading
.\or Windows separators:runtime.test.ts.Related work
generate_in_scope_files.pyhelper and unified Deep Scan with Standard Scan phases. It introduced the affected Deep Scan generator path but did not force canonical separators or assert them on native Windows. It is the relevant causal change, not a fix.generate_in_scope_files.py, does not exercise this Deep Scan setup path, and does not fix the observed failure. Its POSIX filename-preservation requirements are relevant to choosing a safe correction.No open or closed issue, comment, PR, or open PR file list found an exact report or pending fix for this failure.
Privacy