Skip to content

fix(scan): preserve tracked files without exposing ignored files - #320

Open
mldangelo-oai wants to merge 7 commits into
mainfrom
mdangelo/codex/respect-scan-inventory-gitignore-20260808
Open

fix(scan): preserve tracked files without exposing ignored files#320
mldangelo-oai wants to merge 7 commits into
mainfrom
mdangelo/codex/respect-scan-inventory-gitignore-20260808

Conversation

@mldangelo-oai

@mldangelo-oai mldangelo-oai commented Aug 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • preserve every safe Git-tracked source file while excluding ignored and private local-only files
  • respect repository, nested-worktree, and .git/info/exclude policies without inheriting parent/global ripgrep configuration
  • sanitize Git environment, disable repository-controlled fsmonitor, reject tracked symlinks, and fail closed on fatal Git metadata errors
  • support non-Git snapshots and normalize duplicate path identities across Windows/Git separators

Verification

  • bun test --timeout 30000 tests-ts/scan-inventory.test.ts tests-ts/runtime.test.ts -t 'inventory|ignored tracked'
  • exercised the no-ripgrep CI fallback with PATH=/usr/bin:/bin
  • companion monorepo plugin suite: 28 passing Git/ignore/path-security regression tests
  • pnpm run types and prettier checks

Companion internal source PR: https://github.com/openai/openai/pull/1262966

@github-actions github-actions Bot added the bug Something isn't working label Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 45f56e891a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

def generate_in_scope_files(repository: Path, scope: str, output: Path) -> int:
"""Atomically write the exact ripgrep inventory sorted as ``LC_ALL=C``."""
command = ["rg", "--files", "--hidden", "--no-ignore", "--glob", "!.git/**", "--", scope]
command = ["rg", "--files", "--hidden", "--glob", "!.git/**", "--", scope]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve ignored files that are already tracked

When a repository force-tracks a file that still matches .gitignore, this command silently omits that committed file from the security inventory; for example, the tracked tracked-secret.py scenario in tests-ts/runtime.test.ts now produces only .gitignore, so both the existing regression test and scans of such repositories fail to cover committed source. Exclude ignored untracked files without dropping files reported by Git as tracked.

Useful? React with 👍 / 👎.

def generate_in_scope_files(repository: Path, scope: str, output: Path) -> int:
"""Atomically write the exact ripgrep inventory sorted as ``LC_ALL=C``."""
command = ["rg", "--files", "--hidden", "--no-ignore", "--glob", "!.git/**", "--", scope]
command = ["rg", "--files", "--hidden", "--glob", "!.git/**", "--", scope]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Respect ignore files for non-Git directory scans

When --repo points to a supported non-Git directory snapshot, this still inventories files such as an ignored .env and descendants of ignored directories. The local rg --help documents the cause: “By default, ripgrep will only respect filter rules from source control ignore files when ripgrep detects” a Git repository. The new test initializes Git, so it misses this path; make ripgrep honor ignore files even when no .git directory is present.

Useful? React with 👍 / 👎.

Comment on lines +66 to +69
expect((await readFile(output, "utf8")).trimEnd().split("\n")).toEqual([
"./.gitignore",
"./.visible-config",
"./src/handler.ts",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Normalize the asserted inventory paths on Windows

On every windows-latest test leg in .github/workflows/node-ci.yml, this exact array uses Unix separators even though the local rg --help says output “defaults to your platform's path separator”; ripgrep therefore emits backslash-separated paths on Windows and this newly added test fails despite a correct inventory. Normalize the returned paths or make the expected values platform-specific.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 45f56e891a

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

def generate_in_scope_files(repository: Path, scope: str, output: Path) -> int:
"""Atomically write the exact ripgrep inventory sorted as ``LC_ALL=C``."""
command = ["rg", "--files", "--hidden", "--no-ignore", "--glob", "!.git/**", "--", scope]
command = ["rg", "--files", "--hidden", "--glob", "!.git/**", "--", scope]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Security: Preserve ignored tracked files in Deep Scan inventories

When a Deep Scan targets a repository where an untrusted contributor can commit ignore rules, removing --no-ignore lets those rules hide still-tracked source from rg. The bundled setup accepts the truncated inventory, gives it to every worker, and later derives deep_repository/repository coverage with no excluded paths; completion never reconciles it against Git. A contributor can therefore hide arbitrary production source and obtain a sealed “complete” scan that never reviews it. Enumerate tracked files independently and add only non-ignored untracked files.

Useful? React with 👍 / 👎.

@mldangelo-oai mldangelo-oai changed the title fix(scan): keep ignored files out of security inventories fix(scan): preserve tracked files without exposing ignored files Aug 8, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b6677984b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +126 to +127
if relative and (repository / os.fsdecode(relative)).is_file():
rows.add(prefix + relative + b"\n")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Exclude symlinks from the tracked-file supplement

When an untrusted checkout force-tracks an ignored symlink whose target is a regular file outside the repository, Path.is_file() follows the link, so the new Git supplement adds that path even though ripgrep does not enumerate the symlink. Deep Scan workers are instructed to read every inventory entry, which can expose host files such as credentials to the scan; reject symlinks and verify that each resolved file remains beneath repository before adding it.

Useful? React with 👍 / 👎.

Comment on lines +103 to +104
"--",
scope,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass the Git scope as a literal pathspec

When the requested scope has Git pathspec syntax in its literal name, Git interprets it rather than confining the query to that path; Git's pathspec documentation defines a leading : as a “magic signature,” and -- only terminates option parsing. For example, with a real directory named :(exclude)foo, this command returns ignored tracked files outside that directory while omitting its own tracked files, causing a scoped scan to inventory unauthorized paths. Invoke ls-files with literal-pathspec handling so scope is treated only as a filesystem path.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: b6677984b7

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment on lines +100 to +101
"--ignored",
"--exclude-standard",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Security: Recover files hidden by ripgrep-only ignore rules

When an untrusted contributor can commit .ignore or .rgignore, this still lets a Deep Scan seal incomplete coverage: rg now honors those rules, but the recovery asks Git only for --exclude-standard, which does not know ripgrep-only rules. In a root Git repository with tracked hidden.py named by committed .ignore, the helper omitted hidden.py while git ls-files confirmed it was tracked. Workers receive only this canonical inventory, so the omission is not recorded as an exclusion. This is fresh evidence beyond the earlier .gitignore report: the new Git recovery fixes Git ignores but not ripgrep-only ignores. Union the inventory with all tracked regular files.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 540bbd4802

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

command = ["rg", "--files", "--hidden", "--no-ignore", "--glob", "!.git/**", "--", scope]
"""Atomically inventory visible files and ignored files tracked by Git."""
command = [
"rg",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Disable ripgrep configuration when building inventories

When RIPGREP_CONFIG_PATH names a config containing --follow, an untrusted checkout's symlink to a regular file outside the repository is emitted into this inventory and can expose that host file to scan workers. This reproduces independently of the earlier Git-supplement issue: the entry comes directly from ripgrep because its inherited config remains enabled. The inspected rg --help states that --follow traverses symbolic links and that --no-config prevents reading RIPGREP_CONFIG_PATH; add the latter so user configuration cannot alter this security boundary.

Useful? React with 👍 / 👎.

rows = sorted(inventory)
rows = set(inventory)

if (repository / ".git").exists():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Verify Git metadata before invoking ls-files

When a supported non-Git directory snapshot merely contains a .git file or directory without valid repository metadata—for example, a copied submodule with a stale gitfile or a fixture with an empty .git directory—this condition runs git ls-files, receives status 128, and aborts the entire inventory instead of scanning it as a directory. This is inconsistent with the rev-parse-based Git classification in workbench_target.py; use an actual work-tree check rather than filesystem existence before enabling the supplement.

Useful? React with 👍 / 👎.

"rg",
"--files",
"--hidden",
"--no-require-git",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Confine ignore discovery to the requested repository

When a non-Git snapshot is located beneath an unrelated parent .gitignore, that parent can silently remove files from this inventory; for example, a parent rule snapshot/hidden.py causes --repo snapshot --scope . to record only the other files. This is distinct from the earlier non-Git issue about honoring the snapshot's own ignore file: the inspected rg --help states that ripgrep ascends parent directories for ignore rules by default, so content outside --repo is controlling scan coverage. Pass --no-ignore-parent so only ignore rules within the requested repository affect the inventory.

Useful? React with 👍 / 👎.

command = [
"git",
"--literal-pathspecs",
"ls-files",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Disable fsmonitor before running Git in an untrusted repository

When the scanned repository's local .git/config sets core.fsmonitor to an executable hook, this newly introduced git ls-files call executes that hook with the scanner's privileges. I reproduced this through the helper with an executable core.fsmonitor value, and GIT_TRACE2=1 showed child_start for that executable during the exact ls-files --cached --ignored --exclude-standard command. Override core.fsmonitor=false for this invocation so inspecting an untrusted repository cannot execute repository-configured code.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: 540bbd4802

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment on lines +138 to +140
candidate = repository / os.fsdecode(relative)
if candidate.is_symlink() or not candidate.is_file():
continue

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Security: Recurse into ignored tracked submodules

When a whole-target Deep Scan contains an initialized submodule matched by an ignore rule, recurse into the submodule instead of dropping its gitlink. In a fixture where the superproject tracks module and ignores module/, git ls-files --ignored returns only module; candidate.is_file() is false, so module/security.py disappears while setup succeeds. Workers receive this truncated inventory, which can still back deep_repository coverage. Fresh evidence beyond the prior tracked-file reports is that this file is tracked in the nested submodule index, which the root-only recovery never queries. Enumerate initialized submodule indexes with the same containment checks.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 52b82f9444

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 52b82f9444

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

raise InventoryError(f"could not inspect Git worktree: {error}") from error
worktree = None

if worktree is not None and worktree.returncode not in (0, 128):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail closed on fatal Git worktree probe errors

When an actual checkout makes rev-parse exit 128—for example, Git rejects a checkout owned by another UID with fatal: detected dubious ownership—this treats it as a non-Git snapshot and silently skips the tracked-file supplement. I reproduced this with a force-tracked ignored hidden.py: the helper exited successfully while inventorying only .gitignore, allowing incomplete scan coverage. Fresh evidence beyond the earlier stale-.git case is that status 128 also represents fatal errors in valid repositories, so distinguish “not a repository” from probe failures and fail closed for the latter.

Useful? React with 👍 / 👎.

candidate.resolve(strict=True).relative_to(repository)
except (OSError, ValueError):
continue
rows.add(prefix + relative + b"\n")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Canonicalize separators before unioning inventory paths

On Windows, every visible tracked file can be added twice because ripgrep and Git spell the same path differently: the inspected rg --help says its output defaults to \ on Windows, while git ls-files emits slash-form index paths, and this byte-set union does not normalize either source. Fresh evidence beyond the earlier assertion-only issue is that its fixture tracks only files hidden from ripgrep, so normalizing expected strings masks the production duplication rather than exercising the overlap; a normal tracked source tree therefore gets inflated counts and duplicate worker assignments.

Useful? React with 👍 / 👎.

"--files",
"--hidden",
"--no-require-git",
"--no-ignore-parent",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve repository excludes for nested scopes

When a scoped scan targets a subdirectory, this flag also prevents ripgrep from applying the repository's .git/info/exclude, while the manual recovery below restores only .gitignore, .ignore, and .rgignore. I reproduced a sub/hidden.py that git check-ignore -v attributes to .git/info/exclude: a whole-repository inventory omitted it, but --scope sub included it and exited successfully. The inspected rg --help confirms that --no-ignore-parent suppresses applicable parent-directory rules, so preserve repository-local Git excludes explicitly or private ignored files can be sent to scan workers.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bb7c5ce615

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +141 to +142
if worktree.returncode == 128 and "not a git repository" in detail.lower():
worktree = None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make non-repository detection locale independent

On hosts with Git translation catalogs and a non-English LC_MESSAGES, git rev-parse localizes this fatal diagnostic, so a supported non-Git directory snapshot no longer matches the English substring and the helper exits with an inventory error instead of scanning it. Force a stable locale for the Git subprocesses or distinguish the non-repository result without parsing localized stderr.

Useful? React with 👍 / 👎.

if worktree is not None and worktree.stdout.strip() == b"true":
prefix = b"./" if scope == "." or scope.startswith("./") else b""
listed: list[bytes] = []
for arguments in (["--cached"], ["--others", "--exclude-standard"]):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep global Git excludes out of the inventory filter

When the scanning account configures core.excludesFile with a rule matching an untracked source file, git ls-files --others --exclude-standard omits that file and the allowed intersection later deletes it from ripgrep's output, even though ripgrep was deliberately invoked with --no-ignore-global. For example, a global *.py rule makes an untracked source.py disappear while the helper succeeds with incomplete coverage; the inspected git ls-files -h describes this option as adding the standard Git exclusions. Disable the global excludes source for this Git query while retaining repository-local ignore and .git/info/exclude behavior.

Useful? React with 👍 / 👎.

Comment on lines +83 to +86
for name in (".gitignore", ".ignore", ".rgignore"):
ignore = repository / name
if ignore.is_file() and not ignore.is_symlink():
command.extend(["--ignore-file", str(ignore)])

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Disable automatic loading of symlinked ignore files

When a non-Git snapshot contains a root .gitignore, .ignore, or .rgignore symlink, this check prevents only the explicit --ignore-file argument; ripgrep still discovers and follows the symlink automatically. In a reproduced snapshot where .ignore pointed outside the target to a file containing hidden.py, the helper silently omitted the in-scope hidden.py, so outside-target filesystem contents can control scan coverage despite the apparent symlink guard. Disable automatic loading for these files and explicitly supply only validated regular ignore files, including any supported nested rules, or reject symlinked ignore files.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Security Review

Here are some automated security review suggestions for this pull request.

Reviewed commit: bb7c5ce615

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Comment on lines +75 to +79
"--files",
"--hidden",
"--no-require-git",
"--no-ignore-parent",
"--no-ignore-global",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Security: Disable automatic loading of symlinked ignore files

On Unix, when a contributor can commit a symlinked .ignore, .rgignore, or .gitignore and an operator starts Deep Scan, ripgrep still auto-loads it: --no-config and the is_symlink() check do not disable automatic ignore discovery. A tracked .ignore -> /dev/zero made this helper exceed a 2-second timeout, while rg reached approximately 96 MB RSS after 0.5 seconds; the parent --no-ignore behavior returned immediately. Disable automatic discovery and load only contained regular ignore files, with a subprocess resource bound as defense in depth.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1baf11d67c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +134 to +135
worktree = subprocess.run(
[*git, "rev-parse", "--is-inside-work-tree"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Require the Git top level to equal --repo

When a selected non-Git snapshot is nested beneath an unrelated Git working tree, this probe returns true and the later git ls-files --others --exclude-standard query applies the ancestor repository's exclusions; the local git ls-files -h describes that flag as adding the standard Git exclusions. I reproduced an ancestor .gitignore rule for snapshot/hidden.py causing that file to be removed by the allowed intersection even though ripgrep now uses --no-ignore-parent. Fresh evidence beyond the earlier ripgrep parent-ignore report is that this later Git classification reintroduces the ancestor rule; verify rev-parse --show-toplevel equals repository before enabling Git filtering, as the classification in workbench_target.py already does.

Useful? React with 👍 / 👎.

Comment on lines +218 to +220
if (path := normalized(row.rstrip(b"\r\n"))) in allowed
or any(path.startswith(worktree) for worktree in nested_worktrees)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve scopes that traverse in-repository symlinks

When a relative scope is a symlink to a directory inside the repository, ripgrep emits paths using the requested alias but git ls-files reports only the canonical target paths (or the symlink itself), so this intersection removes every descendant. I reproduced a tracked d/a with linkdir -> d: --scope linkdir previously inventoried linkdir/a but now succeeds with zero files. Either reject symlinked directory scopes during resolution or reconcile the Git results using the resolved scope so an accepted scoped scan cannot silently become empty.

Useful? React with 👍 / 👎.

rows = {
row
for row in rows
if (path := normalized(row.rstrip(b"\r\n"))) in allowed

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Strip only the record newline from ripgrep paths

On Unix, an untracked visible file whose name ends with a carriage return is silently removed because rstrip(b"\r\n") strips both the output delimiter and the carriage return that belongs to the filename, so the resulting key no longer matches the NUL-delimited git ls-files entry. I reproduced a repository containing only visible\r: ripgrep emitted ./visible\r\n, Git emitted visible\r\0, and the helper reported zero files. This filename form is intentionally handled by normalize_candidates.py::read_scope, so remove only the actual line delimiter rather than all trailing CR/LF bytes.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 1baf11d67c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@mldangelo-oai
mldangelo-oai marked this pull request as ready for review August 8, 2026 07:17

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Security review completed. No security issues were found in this pull request.

Reviewed commit: 1baf11d67c

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1baf11d67c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

for arguments in (["--cached"], ["--others", "--exclude-standard"]):
try:
result = subprocess.run(
[*git, "ls-files", *arguments, "-z", "--", scope],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve scopes below embedded Git worktrees

When --scope names a directory below an embedded Git worktree, such as nested/src, this outer-repository git ls-files ... -- nested/src query returns neither the descendant files nor the nested/ boundary entry that is returned for a whole-repository query. Consequently allowed and nested_worktrees are empty and the later intersection removes every file found by ripgrep, producing a successful zero-file scoped scan. Detect the enclosing nested-worktree boundary independently of the descendant pathspec or enumerate the nested worktree for such scopes.

Useful? React with 👍 / 👎.

"GIT_WORK_TREE",
):
environment.pop(name, None)
environment["GIT_LITERAL_PATHSPECS"] = "1"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear incompatible Git pathspec environment flags

When the scanner inherits GIT_GLOB_PATHSPECS=1 or GIT_ICASE_PATHSPECS=1, forcing GIT_LITERAL_PATHSPECS=1 leaves mutually incompatible global pathspec modes enabled. Git then aborts every repository inventory at ls-files with fatal: global 'literal' pathspec setting is incompatible with all other global pathspec settings, even for scope .. Remove the incompatible pathspec environment variables before selecting literal semantics so a user's Git environment cannot prevent scans from starting.

Useful? React with 👍 / 👎.

Comment on lines +134 to +140
worktree = subprocess.run(
[*git, "rev-parse", "--is-inside-work-tree"],
cwd=repository,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=environment,
check=False,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bound Git probes against blocking config includes

When the selected repository's local .git/config includes a FIFO or another blocking file, this newly added Git probe waits indefinitely because it has no timeout or resource bound. For example, an [include] path = /path/to/fifo entry causes the exact rev-parse invocation here to block before producing output, so setup for a scan of repository metadata that is not trusted never completes. Run these Git inspections with a finite timeout or otherwise prevent blocking config includes from stalling inventory generation.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant