[GH-ISSUE #5619] [Bug] Reference-source import excludes files that Git leaves unignored with core.ignorecase=false #3406

Closed
opened 2026-10-31 00:40:01 +00:00 by bsakaguchi · 1 comment
Owner

Originally created by @coygeek on GitHub (Oct 20, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/5619

Before submitting

  • I searched the open and closed issues for a related report.
  • I removed credentials, tokens, private paths, and sensitive target data.

Area

Evidence, artifacts, or reconstruction

Observed behavior

node scripts/rea.mjs import-reference-source "$SOURCE" --json excludes lower.tmp for the root .gitignore pattern *.TMP, even when the selected repository explicitly sets core.ignorecase=false. Git's check-ignore excludes only keep.TMP for that configuration. REA exits 0 with empty stderr, inventories only .gitignore, and records both data files as project-ignored.

An independent verifier reproduced this through the built CLI, including the controls below. The fixture filesystem was case-insensitive; the repository's explicit Git setting establishes the mismatch.

Reproduction

From the built source checkout at the revision below, the verifier executed this sequence with isolated configuration and output outside the imported tree:

set -eu
CASE="$(mktemp -d)"
SOURCE="$CASE/source"
mkdir -p "$SOURCE" "$CASE/home" "$CASE/config" "$CASE/data" "$CASE/cache" "$CASE/state" "$CASE/temp"
trial() {
  env -i PATH="$PATH" HOME="$CASE/home" USERPROFILE="$CASE/home" \
    XDG_CONFIG_HOME="$CASE/config" XDG_DATA_HOME="$CASE/data" \
    XDG_CACHE_HOME="$CASE/cache" XDG_STATE_HOME="$CASE/state" \
    TMPDIR="$CASE/temp" GIT_CONFIG_NOSYSTEM=1 "$@"
}
trial git init -q -b main "$SOURCE"
trial git -C "$SOURCE" config core.ignorecase false
printf '*.TMP\n' > "$SOURCE/.gitignore"
printf 'a\n' > "$SOURCE/keep.TMP"
printf 'b\n' > "$SOURCE/lower.tmp"
trial git -C "$SOURCE" check-ignore -v --no-index keep.TMP lower.tmp
trial node scripts/rea.mjs import-reference-source "$SOURCE" --json > "$CASE/graph.json"
trial node -e 'const g=require(process.argv[1]); console.log(JSON.stringify({entries:g.entries.map(e=>e.path), exclusions:g.exclusions, inventory_state:g.inventory_state},null,2))' "$CASE/graph.json"

Executed controls: set core.ignorecase=true and repeat the Git check and import; both then exclude both data files. Remove .gitignore and repeat the import; both files then appear with content_state: "hashed". These controls rule out unsupported extensions and default exclusions as the reason for the lowercase omission. No Linux runtime was tested.

Expected behavior

docs/cli.md:307 documents that historical-source import honors the source tree's .gitignore, separately from default exclusions. For the explicit core.ignorecase=false configuration, Git's executed check leaves lower.tmp unignored. REA should inventory and hash that file while retaining the project exclusion for keep.TMP. Matching should also agree with the executed core.ignorecase=true control.

Impact and scope

P2: a valid, unignored file is omitted from the historical inventory, changing the file set available to downstream analysis for this repository configuration. The omitted path and matched pattern remain visible in exclusions, and the graph reports inventory_state: "partial". No source bytes were lost or mutated, and no severe downstream harm was observed. Frequency in real repositories is unknown.

A result-preserving workaround was not established. Removing the policy inventories both files but loses the intended project exclusions. Changing Git configuration did not change REA's matching.

REA version

6.7.0; source commit 074768901f3cdc8205b61773fb1faf6f6c7b3ca8, built checkout with installed dependencies. Latest published release checked: rea-agents-6.7.0.

Runtime and platform

Node.js v26.12.0; Git 2.56.0; macOS arm64, case-insensitive fixture filesystem. NOT_ENOUGH_INFO: the verifier did not record the exact macOS version. No native analysis provider was involved.

Target and artifact context

Synthetic local Git source tree with root .gitignore containing *.TMP, and two regular files, keep.TMP and lower.tmp. Output is the historical-source inventory graph; no executable target or provider database is needed.

Interface

CLI

Earliest failure stage

Artifact or evidence registration

Relevant output or evidence

The executed false-setting Git check prints only the match for keep.TMP; lower.tmp is absent. The executed REA graph instead includes:

{"path":"lower.tmp","entry_kind":"file","reason":"project-ignored","pattern":"*.TMP"}

The graph's only file entry is .gitignore; .git is separately default-ignored. REA exits 0 with empty stderr. Both true-setting and no-policy controls completed successfully with the results stated above.

Typed outcome or recovery expected

Proposed restoration check: with core.ignorecase=false, retain a hashed lower.tmp entry and the uppercase file's project-exclusion provenance. With core.ignorecase=true, retain both project exclusions. With no policy file, retain both hashed data files. Preserve default exclusions and partial-inventory metadata. Always forcing case-sensitive matching would fail the true-setting control.

Analysis or suspected cause

Source-derived explanation: src/application/ReferenceSourceImportPolicy.ts:88 constructs ignore() without options and line 131 adds the project policy. The installed ignore dependency defaults ignorecase to true at node_modules/ignore/index.js:605, consistent with the observed results under both Git configurations. Runtime reproduction establishes the omission; this source inspection explains the likely cause.

Additional context

Prepared with AI assistance and independently reproduced. NOT_ENOUGH_INFO: no last-known-good release was tested.

Upstream origin/main was fetched and checked at 5b676ba9f302228b44c28ab076525abed3e647c1. Since the reproduced baseline, the ignore-policy implementation and import entry points are unchanged; changes in docs/cli.md concern other commands and output filtering. No runtime replay on that later revision is claimed. Searches included open and closed issues and PRs. PRs #2630 and #5472 expose caller-selected exclusions; merged PR #1770 handles other historical-source facts. None reports this Git case-setting mismatch.

Originally created by @coygeek on GitHub (Oct 20, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/5619 ### Before submitting - [x] I searched the open and closed issues for a related report. - [x] I removed credentials, tokens, private paths, and sensitive target data. ### Area Evidence, artifacts, or reconstruction ### Observed behavior `node scripts/rea.mjs import-reference-source "$SOURCE" --json` excludes `lower.tmp` for the root `.gitignore` pattern `*.TMP`, even when the selected repository explicitly sets `core.ignorecase=false`. Git's `check-ignore` excludes only `keep.TMP` for that configuration. REA exits 0 with empty stderr, inventories only `.gitignore`, and records both data files as `project-ignored`. An independent verifier reproduced this through the built CLI, including the controls below. The fixture filesystem was case-insensitive; the repository's explicit Git setting establishes the mismatch. ### Reproduction From the built source checkout at the revision below, the verifier executed this sequence with isolated configuration and output outside the imported tree: ```sh set -eu CASE="$(mktemp -d)" SOURCE="$CASE/source" mkdir -p "$SOURCE" "$CASE/home" "$CASE/config" "$CASE/data" "$CASE/cache" "$CASE/state" "$CASE/temp" trial() { env -i PATH="$PATH" HOME="$CASE/home" USERPROFILE="$CASE/home" \ XDG_CONFIG_HOME="$CASE/config" XDG_DATA_HOME="$CASE/data" \ XDG_CACHE_HOME="$CASE/cache" XDG_STATE_HOME="$CASE/state" \ TMPDIR="$CASE/temp" GIT_CONFIG_NOSYSTEM=1 "$@" } trial git init -q -b main "$SOURCE" trial git -C "$SOURCE" config core.ignorecase false printf '*.TMP\n' > "$SOURCE/.gitignore" printf 'a\n' > "$SOURCE/keep.TMP" printf 'b\n' > "$SOURCE/lower.tmp" trial git -C "$SOURCE" check-ignore -v --no-index keep.TMP lower.tmp trial node scripts/rea.mjs import-reference-source "$SOURCE" --json > "$CASE/graph.json" trial node -e 'const g=require(process.argv[1]); console.log(JSON.stringify({entries:g.entries.map(e=>e.path), exclusions:g.exclusions, inventory_state:g.inventory_state},null,2))' "$CASE/graph.json" ``` Executed controls: set `core.ignorecase=true` and repeat the Git check and import; both then exclude both data files. Remove `.gitignore` and repeat the import; both files then appear with `content_state: "hashed"`. These controls rule out unsupported extensions and default exclusions as the reason for the lowercase omission. No Linux runtime was tested. ### Expected behavior `docs/cli.md:307` documents that historical-source import honors the source tree's `.gitignore`, separately from default exclusions. For the explicit `core.ignorecase=false` configuration, Git's executed check leaves `lower.tmp` unignored. REA should inventory and hash that file while retaining the project exclusion for `keep.TMP`. Matching should also agree with the executed `core.ignorecase=true` control. ### Impact and scope P2: a valid, unignored file is omitted from the historical inventory, changing the file set available to downstream analysis for this repository configuration. The omitted path and matched pattern remain visible in `exclusions`, and the graph reports `inventory_state: "partial"`. No source bytes were lost or mutated, and no severe downstream harm was observed. Frequency in real repositories is unknown. A result-preserving workaround was not established. Removing the policy inventories both files but loses the intended project exclusions. Changing Git configuration did not change REA's matching. ### REA version 6.7.0; source commit `074768901f3cdc8205b61773fb1faf6f6c7b3ca8`, built checkout with installed dependencies. Latest published release checked: `rea-agents-6.7.0`. ### Runtime and platform Node.js v26.12.0; Git 2.56.0; macOS arm64, case-insensitive fixture filesystem. NOT_ENOUGH_INFO: the verifier did not record the exact macOS version. No native analysis provider was involved. ### Target and artifact context Synthetic local Git source tree with root `.gitignore` containing `*.TMP`, and two regular files, `keep.TMP` and `lower.tmp`. Output is the historical-source inventory graph; no executable target or provider database is needed. ### Interface CLI ### Earliest failure stage Artifact or evidence registration ### Relevant output or evidence The executed false-setting Git check prints only the match for `keep.TMP`; `lower.tmp` is absent. The executed REA graph instead includes: ```json {"path":"lower.tmp","entry_kind":"file","reason":"project-ignored","pattern":"*.TMP"} ``` The graph's only file entry is `.gitignore`; `.git` is separately default-ignored. REA exits 0 with empty stderr. Both true-setting and no-policy controls completed successfully with the results stated above. ### Typed outcome or recovery expected Proposed restoration check: with `core.ignorecase=false`, retain a hashed `lower.tmp` entry and the uppercase file's project-exclusion provenance. With `core.ignorecase=true`, retain both project exclusions. With no policy file, retain both hashed data files. Preserve default exclusions and partial-inventory metadata. Always forcing case-sensitive matching would fail the true-setting control. ### Analysis or suspected cause Source-derived explanation: `src/application/ReferenceSourceImportPolicy.ts:88` constructs `ignore()` without options and line 131 adds the project policy. The installed `ignore` dependency defaults `ignorecase` to true at `node_modules/ignore/index.js:605`, consistent with the observed results under both Git configurations. Runtime reproduction establishes the omission; this source inspection explains the likely cause. ### Additional context Prepared with AI assistance and independently reproduced. NOT_ENOUGH_INFO: no last-known-good release was tested. Upstream `origin/main` was fetched and checked at `5b676ba9f302228b44c28ab076525abed3e647c1`. Since the reproduced baseline, the ignore-policy implementation and import entry points are unchanged; changes in `docs/cli.md` concern other commands and output filtering. No runtime replay on that later revision is claimed. Searches included open and closed issues and PRs. PRs #2630 and #5472 expose caller-selected exclusions; merged PR #1770 handles other historical-source facts. None reports this Git case-setting mismatch.
Author
Owner

@matbrgz commented on GitHub (Oct 20, 2026):

Cross-referencing with related issue #5399 ([Bug] Reference-source import root errors omit required machine-readable fields). Both address path filtering, case sensitivity (core.ignorecase), and error handling in import-reference-source. Cataloged under Cluster BJ in consolidation tracker #4330.

<!-- gh-comment-id:6296082853 --> @matbrgz commented on GitHub (Oct 20, 2026): Cross-referencing with related issue #5399 (`[Bug] Reference-source import root errors omit required machine-readable fields`). Both address path filtering, case sensitivity (`core.ignorecase`), and error handling in `import-reference-source`. Cataloged under Cluster BJ in consolidation tracker #4330.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#3406
No description provided.