[PR #5472] feat(cli): expose caller-selected reference-source exclusions #6934

Open
opened 2026-11-01 21:44:09 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/5472
Author: @MANAKAVOO-SIVA-BALAJI
Created: 10/20/2026
Status: 🔄 Open

Base: main ← Head: feat/cli-reference-source-exclusions


📝 Commits (1)

  • 22d11ab feat(cli): expose caller-selected reference-source exclusions

📊 Changes

8 files changed (+521 additions, -1 deletions)

View changed files

📝 docs/cli.md (+19 -0)
📝 src/application/ReferenceSourceImportPolicy.ts (+7 -1)
📝 src/cli/utilityCommands.ts (+63 -0)
➕ src/domain/referenceSourceExclusionRules.test.ts (+106 -0)
➕ src/domain/referenceSourceExclusionRules.ts (+72 -0)
➕ tests/boundary/cli/referenceSourceExclusionInput.test.ts (+91 -0)
📝 tests/boundary/cli/referenceSourceExclusions.test.ts (+91 -0)
➕ tests/boundary/filesystem/referenceSourceExclusionPolicy.test.ts (+72 -0)

📄 Description

Summary

import-reference-source could not pass caller-selected path exclusions to the
reference-source importer. The importer already accepted exclusion rules,
recorded caller-excluded provenance and pruned traversal, but no CLI caller
could reach that behavior, so an analyst could not omit irrelevant repository
paths from an imported source tree.

Fixes #2443

Problem and expected behavior

An analyst comparing an older source tree with the current artifact often wants
to omit paths that carry no signal (vendored dependencies, generated output,
scratch files). REA's importer already models this choice, but the CLI exposes
no way to make it.

Expected behavior: rea import-reference-source <root> --exclude-paths '["vendor","*.tmp"]' omits the matching paths from the imported tree, reports
each omission as a caller-excluded exclusion with its matched pattern, and
never traverses an excluded directory. Malformed JSON and rejected rules fail
the command before the import starts.

Change and scope

  • New domain module src/domain/referenceSourceExclusionRules.ts owns the
    rule grammar: a rule is a nonempty string without control characters, stays
    relative to the imported root, and the accepted rule count is bounded.
  • import-reference-source gains an optional --exclude-paths option that
    carries a JSON array of those rules. The CLI decodes and validates the value
    before any import work and reports rejected input against excludePaths.
  • src/application/ReferenceSourceImportPolicy.ts keeps a directory-only
    caller rule as written instead of deriving a second pattern (vendor//)
    that matches nothing.
  • docs/cli.md documents the option, its grammar, its failure behavior and its
    precedence against project, default and configured-secret rules.

Not included: the MCP surface (the importer is a CLI workflow today), a
secrecy heuristic for exclusions (an explicit exclusion is a context choice),
and the docs/specs/reference-source/caller-exclusions/ files named in the
issue.

Contract and boundary impact

  • Semantic owner and earliest changed stage: the new domain module owns the
    rule grammar; the CLI adapter decodes the caller's JSON text and delegates.
  • Contribution scope fit and linked maintainer decision: additive CLI control
    inside existing boundaries; not applicable.
  • CLI and MCP/tool-catalog contract: import-reference-source gains one
    optional CLI option. No MCP tool changes.
  • Provider, bridge, target-format, or platform compatibility: unchanged. The
    import itself still requires safe no-follow file opens, so it runs on Linux
    and macOS, not native Windows.
  • Evidence, artifact, provenance, or reconstruction contract: excluded paths
    keep the existing caller-excluded reason and matched pattern in the
    committed graph. Project, default and configured-secret rules keep their own
    precedence.
  • Target selection, authority, upstream behavior, and cleanup details: not
    applicable.
  • Generated metadata (docs/public/product-catalog.json), package, or
    installation impact: none; CI regenerates the ignored catalogs.

Expected effects:

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated:
    • src/domain/referenceSourceExclusionRules.test.ts — rule grammar, bounds
      and correction metadata.
    • tests/boundary/cli/referenceSourceExclusionInput.test.ts — compiled CLI
      rejects malformed JSON, a non-array value, a non-string rule, a blank rule
      and an absolute host path rule before the import starts.
    • tests/boundary/cli/referenceSourceExclusions.test.ts — compiled CLI
      prunes caller-excluded paths with their provenance, matches a wildcard rule,
      and keeps the default import unchanged for an empty rule list. This file's
      import-dependent cases are skipped on native Windows, because the import
      requires safe no-follow file opens.
    • tests/boundary/filesystem/referenceSourceExclusionPolicy.test.ts — the
      importer's matcher marks caller rules apart from default rules and keeps a
      directory-only rule away from a file with the same name.
  • Base reproduction or other evidence: before this change the CLI had no
    --exclude-paths option and importReferenceSource was called without
    excludePaths, so no caller rule could reach the importer.
  • User-visible CLI/MCP output:
$ rea import-reference-source /path/to/source --exclude-paths '["vendor",7]' --json
{"error":"Import failed","code":"invalid_request","category":"invalid_input","message":"--exclude-paths must be a JSON array of Git-ignore-style path rules.","retryable":true,"remediation":{"action":"Correct the listed arguments and retry."},"details":{"operation":"import-reference-source","issues":[{"path":["excludePaths",1],"reason":"invalid_type","expected":"string"}]}}
  • Remaining proof gaps: the end-to-end import path (pruning, wildcard rules and
    the empty-array comparison) was not executed on this Windows host, because the
    reference-source import requires safe no-follow file opens and returns
    unsupported_host on native Windows. Those cases run on Linux and macOS
    CI.

Validation performed

  • npx vitest run --project domain src/domain/referenceSourceExclusionRules.test.ts — 8 passed.
  • npx vitest run --project boundary tests/boundary/filesystem/referenceSourceExclusionPolicy.test.ts — 2 passed.
  • npx vitest run --project cli-boundary tests/boundary/cli/referenceSourceExclusionInput.test.ts tests/boundary/cli/referenceSourceExclusions.test.ts tests/boundary/cli/referenceSourceSummary.test.ts — 15 passed, 6 skipped (the skipped cases need Linux or macOS).
  • npx tsc --noEmit — passed.
  • npx oxlint <changed files> and npx oxfmt --check <changed files> — passed.
  • npx knip — passed.
  • npm run docs:check — passed.
  • npx vitest run --project cli-boundary — 60 files passed, 23 skipped, 14 files failed with 28 failed assertions. Every failure is a pre-existing native-Windows host limit, and the same 14 files fail identically on the base commit: the reference-source cases fail with "Safe no-follow file opens are unavailable", the Electron, Apktool, Cutter, pcap and client-profile cases need tools this host does not provide, and the jsonInputStatus, scenarioCliInputDiagnostics and cliOptionAliases cases expect POSIX-style paths in error messages.
  • npx vitest run --project cli-boundary tests/boundary/cli/cliInputSchemaRequired.test.ts — 5 passed; the advertised input schema accepts the new optional option.
  • node scripts/rea.mjs import-reference-source --help — the option is documented in public command help.
  • node scripts/rea.mjs import-reference-source <root> --exclude-paths ... --json — observed the four rejection outputs above.
  • npx vitest run --project boundary tests/boundary/filesystem/referenceSource — 13 files fail on this Windows host with "Safe no-follow file opens are unavailable". These failures are the host limitation of the existing reference-source suite, not a regression from this change; the same files fail on the base commit.

Compatibility, safety, and release

  • Breaking changes or migration steps: none. The option is optional and its
    absence keeps the current import.
  • Real Hopper/Ghidra, browser, or OS coverage: not applicable. Linux and macOS
    CI cover the import-dependent cases.
  • Package or release metadata impact: none.
  • Security, privacy, process, or containment review: the import still executes
    no source file, hook, build script, remote fetch or LLM request. Exclusions
    are a context choice and are not a secrecy heuristic; configured-secret rules
    keep their own reason.

Author readiness

Human owner: @MANAKAVOO-SIVA-BALAJI

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • This PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/5472 **Author:** [@MANAKAVOO-SIVA-BALAJI](https://github.com/MANAKAVOO-SIVA-BALAJI) **Created:** 10/20/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `feat/cli-reference-source-exclusions` --- ### 📝 Commits (1) - [`22d11ab`](https://github.com/morluto/rea/commit/22d11abff389c57f1cea2121297f900ed5489991) feat(cli): expose caller-selected reference-source exclusions ### 📊 Changes **8 files changed** (+521 additions, -1 deletions) <details> <summary>View changed files</summary> 📝 `docs/cli.md` (+19 -0) 📝 `src/application/ReferenceSourceImportPolicy.ts` (+7 -1) 📝 `src/cli/utilityCommands.ts` (+63 -0) ➕ `src/domain/referenceSourceExclusionRules.test.ts` (+106 -0) ➕ `src/domain/referenceSourceExclusionRules.ts` (+72 -0) ➕ `tests/boundary/cli/referenceSourceExclusionInput.test.ts` (+91 -0) 📝 `tests/boundary/cli/referenceSourceExclusions.test.ts` (+91 -0) ➕ `tests/boundary/filesystem/referenceSourceExclusionPolicy.test.ts` (+72 -0) </details> ### 📄 Description ## Summary `import-reference-source` could not pass caller-selected path exclusions to the reference-source importer. The importer already accepted exclusion rules, recorded `caller-excluded` provenance and pruned traversal, but no CLI caller could reach that behavior, so an analyst could not omit irrelevant repository paths from an imported source tree. Fixes #2443 ## Problem and expected behavior An analyst comparing an older source tree with the current artifact often wants to omit paths that carry no signal (vendored dependencies, generated output, scratch files). REA's importer already models this choice, but the CLI exposes no way to make it. Expected behavior: `rea import-reference-source <root> --exclude-paths '["vendor","*.tmp"]'` omits the matching paths from the imported tree, reports each omission as a `caller-excluded` exclusion with its matched pattern, and never traverses an excluded directory. Malformed JSON and rejected rules fail the command before the import starts. ## Change and scope - New domain module `src/domain/referenceSourceExclusionRules.ts` owns the rule grammar: a rule is a nonempty string without control characters, stays relative to the imported root, and the accepted rule count is bounded. - `import-reference-source` gains an optional `--exclude-paths` option that carries a JSON array of those rules. The CLI decodes and validates the value before any import work and reports rejected input against `excludePaths`. - `src/application/ReferenceSourceImportPolicy.ts` keeps a directory-only caller rule as written instead of deriving a second pattern (`vendor//`) that matches nothing. - `docs/cli.md` documents the option, its grammar, its failure behavior and its precedence against project, default and configured-secret rules. Not included: the MCP surface (the importer is a CLI workflow today), a secrecy heuristic for exclusions (an explicit exclusion is a context choice), and the `docs/specs/reference-source/caller-exclusions/` files named in the issue. ## Contract and boundary impact - Semantic owner and earliest changed stage: the new domain module owns the rule grammar; the CLI adapter decodes the caller's JSON text and delegates. - Contribution scope fit and linked maintainer decision: additive CLI control inside existing boundaries; not applicable. - CLI and MCP/tool-catalog contract: `import-reference-source` gains one optional CLI option. No MCP tool changes. - Provider, bridge, target-format, or platform compatibility: unchanged. The import itself still requires safe no-follow file opens, so it runs on Linux and macOS, not native Windows. - Evidence, artifact, provenance, or reconstruction contract: excluded paths keep the existing `caller-excluded` reason and matched pattern in the committed graph. Project, default and configured-secret rules keep their own precedence. - Target selection, authority, upstream behavior, and cleanup details: not applicable. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: none; CI regenerates the ignored catalogs. Expected effects: - [x] Read existing files or captured data. - [ ] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [ ] Contact network services. - [ ] Recover protected code or work around protections. - [x] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: - `src/domain/referenceSourceExclusionRules.test.ts` — rule grammar, bounds and correction metadata. - `tests/boundary/cli/referenceSourceExclusionInput.test.ts` — compiled CLI rejects malformed JSON, a non-array value, a non-string rule, a blank rule and an absolute host path rule before the import starts. - `tests/boundary/cli/referenceSourceExclusions.test.ts` — compiled CLI prunes caller-excluded paths with their provenance, matches a wildcard rule, and keeps the default import unchanged for an empty rule list. This file's import-dependent cases are skipped on native Windows, because the import requires safe no-follow file opens. - `tests/boundary/filesystem/referenceSourceExclusionPolicy.test.ts` — the importer's matcher marks caller rules apart from default rules and keeps a directory-only rule away from a file with the same name. - Base reproduction or other evidence: before this change the CLI had no `--exclude-paths` option and `importReferenceSource` was called without `excludePaths`, so no caller rule could reach the importer. - User-visible CLI/MCP output: ```console $ rea import-reference-source /path/to/source --exclude-paths '["vendor",7]' --json {"error":"Import failed","code":"invalid_request","category":"invalid_input","message":"--exclude-paths must be a JSON array of Git-ignore-style path rules.","retryable":true,"remediation":{"action":"Correct the listed arguments and retry."},"details":{"operation":"import-reference-source","issues":[{"path":["excludePaths",1],"reason":"invalid_type","expected":"string"}]}} ``` - Remaining proof gaps: the end-to-end import path (pruning, wildcard rules and the empty-array comparison) was not executed on this Windows host, because the reference-source import requires safe no-follow file opens and returns `unsupported_host` on native Windows. Those cases run on Linux and macOS CI. ## Validation performed - `npx vitest run --project domain src/domain/referenceSourceExclusionRules.test.ts` — 8 passed. - `npx vitest run --project boundary tests/boundary/filesystem/referenceSourceExclusionPolicy.test.ts` — 2 passed. - `npx vitest run --project cli-boundary tests/boundary/cli/referenceSourceExclusionInput.test.ts tests/boundary/cli/referenceSourceExclusions.test.ts tests/boundary/cli/referenceSourceSummary.test.ts` — 15 passed, 6 skipped (the skipped cases need Linux or macOS). - `npx tsc --noEmit` — passed. - `npx oxlint <changed files>` and `npx oxfmt --check <changed files>` — passed. - `npx knip` — passed. - `npm run docs:check` — passed. - `npx vitest run --project cli-boundary` — 60 files passed, 23 skipped, 14 files failed with 28 failed assertions. Every failure is a pre-existing native-Windows host limit, and the same 14 files fail identically on the base commit: the reference-source cases fail with "Safe no-follow file opens are unavailable", the Electron, Apktool, Cutter, pcap and client-profile cases need tools this host does not provide, and the `jsonInputStatus`, `scenarioCliInputDiagnostics` and `cliOptionAliases` cases expect POSIX-style paths in error messages. - `npx vitest run --project cli-boundary tests/boundary/cli/cliInputSchemaRequired.test.ts` — 5 passed; the advertised input schema accepts the new optional option. - `node scripts/rea.mjs import-reference-source --help` — the option is documented in public command help. - `node scripts/rea.mjs import-reference-source <root> --exclude-paths ... --json` — observed the four rejection outputs above. - `npx vitest run --project boundary tests/boundary/filesystem/referenceSource` — 13 files fail on this Windows host with "Safe no-follow file opens are unavailable". These failures are the host limitation of the existing reference-source suite, not a regression from this change; the same files fail on the base commit. ## Compatibility, safety, and release - Breaking changes or migration steps: none. The option is optional and its absence keeps the current import. - Real Hopper/Ghidra, browser, or OS coverage: not applicable. Linux and macOS CI cover the import-dependent cases. - Package or release metadata impact: none. - Security, privacy, process, or containment review: the import still executes no source file, hook, build script, remote fetch or LLM request. Exclusions are a context choice and are not a secrecy heuristic; configured-secret rules keep their own reason. ## Author readiness Human owner: @MANAKAVOO-SIVA-BALAJI - [ ] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [ ] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [ ] I declare this PR ready for initial maintainer review. ## Before merge - [ ] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [ ] This PR has one focused outcome and the title follows `type(scope): outcome`. - [ ] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [ ] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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#6934
No description provided.