# How the ignore-filter handles custom .understandignore patterns in Understand-Anything

> Discover how the ignore-filter handles custom .understandignore patterns by merging defaults with user rules via a three-layer precedence system for powerful configuration.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: how-to-guide
- Published: 2026-06-18

---

**The ignore-filter merges hard-coded default patterns with user-defined rules from `.understandignore` files, applying a three-layer precedence system where workspace-specific configurations override project-root settings, which in turn override the built-in defaults.**

The ignore-filter is a core component of the [Egonex-AI/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything) repository that determines which files are excluded from the knowledge-graph analysis pipeline. By combining curated default patterns with custom `.understandignore` configurations, the system gives developers precise control over file inclusion while maintaining sensible out-of-the-box behavior.

## Architecture of the Ignore-Filter System

The filtering logic is centralized in **[[`ignore-filter.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ignore-filter.ts)](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/ignore-filter.ts)**. The primary entry point is the **`createIgnoreFilter(projectRoot)`** function, which instantiates an `ignore` object, populates it with rules from three distinct sources, and returns an `isIgnored` interface for path evaluation.

### Default Ignore Patterns

The engine initializes every filter with **`DEFAULT_IGNORE_PATTERNS`**, a hard-coded array that guards against common noisy files and directories. These defaults include build artifacts (`dist/`, `build/`), dependency folders (`node_modules/`), lock files ([`package-lock.json`](https://github.com/Egonex-AI/Understand-Anything/blob/main/package-lock.json), `yarn.lock`), minified assets (`*.min.js`), IDE configurations (`.vscode/`, `.idea/`), and version-control internals (`.git/`).

### The Three-Layer Precedence Model

When `createIgnoreFilter` executes, it layers rules in the following strict order:

1. **Hard-coded defaults** – Added first via `ig.add(DEFAULT_IGNORE_PATTERNS)`, establishing baseline exclusions.
2. **Project-root `.understandignore`** – Located at the repository root, this file is read and added after the defaults, allowing project-wide customization.
3. **Workspace-specific `.understandanything/.understandignore`** – Located under `.understandanything/.understandignore`, this file is processed last, giving it the highest precedence to override both defaults and root-level rules.

## How Custom Patterns Are Processed

### Loading the Project-Root .understandignore

The filter checks for a file named `.understandignore` at the `projectRoot`. If present, its raw text content is read and passed directly to the underlying `ignore` instance via `ig.add(content)`. Patterns defined here take precedence over the hard-coded defaults but yield to workspace-specific configurations.

### Workspace-Specific Overrides

For monorepo or multi-workspace scenarios, the filter looks for `.understandanything/.understandignore`. Because this file is processed **after** the root ignore file, its patterns can selectively un-ignore paths (using negation patterns like `!path`) or add stricter exclusions that apply only to the current workspace context.

## Practical Usage Examples

The following TypeScript example demonstrates how to instantiate the filter and query file paths:

```typescript
import { createIgnoreFilter } from '@understand-anything/core';

// Initialize the filter for the repository root
const filter = createIgnoreFilter('/my/project');

// Default patterns automatically exclude common artifacts
filter.isIgnored('node_modules/lodash/index.js'); // true
filter.isIgnored('dist/bundle.js');               // true
filter.isIgnored('.git/config');                  // true

// Source files are allowed by default
filter.isIgnored('src/components/Button.tsx');    // false

```

When a custom `.understandignore` exists at the project root, its patterns are evaluated alongside the defaults:

```typescript
// Assuming /my/project/.understandignore contains:
// __tests__/**/*.test.ts

filter.isIgnored('__tests__/unit/auth.test.ts'); // true
filter.isIgnored('src/utils.test.ts');          // true (if matched by pattern)
filter.isIgnored('src/utils.ts');               // false

```

Workspace-specific files can override these rules. If `.understandanything/.understandignore` contains:

```text
!__tests__/keep_this.test.ts

```

Then despite the root file ignoring all `__tests__/**/*.test.ts`, the workspace rule re-includes the specific file:

```typescript
filter.isIgnored('__tests__/keep_this.test.ts'); // false

```

## Key Source Files and References

| File | Purpose | Link |
|------|---------|------|
| [`ignore-filter.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ignore-filter.ts) | Core logic implementing `createIgnoreFilter` and the three-layer merge | [Source](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/ignore-filter.ts) |
| [`ignore-generator.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ignore-generator.ts) | Utility for scaffolding starter ignore files | [Source](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/ignore-generator.ts) |
| [`ignore-filter.test.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ignore-filter.test.ts) | Unit tests verifying default and custom pattern behavior | [Tests](https://github.com/Egonex-AI/Understand-Anything/blob/main/understand-anything-plugin/packages/core/src/__tests__/ignore-filter.test.ts) |
| [`2026-04-10-understandignore-design.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/2026-04-10-understandignore-design.md) | Specification for the `.understandignore` format | [Design Doc](https://github.com/Egonex-AI/Understand-Anything/blob/main/docs/superpowers/specs/2026-04-10-understandignore-design.md) |
| [`2026-04-10-understandignore-impl.md`](https://github.com/Egonex-AI/Understand-Anything/blob/main/2026-04-10-understandignore-impl.md) | Implementation plan detailing precedence rules | [Plan](https://github.com/Egonex-AI/Understand-Anything/blob/main/docs/superpowers/plans/2026-04-10-understandignore-impl.md) |

## Summary

- The **ignore-filter** is implemented in [`ignore-filter.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/ignore-filter.ts) and exposed via the `createIgnoreFilter` function.
- It combines **three layers** of rules: hard-coded defaults, project-root `.understandignore`, and workspace-specific `.understandanything/.understandignore`.
- **Precedence** increases with each layer; workspace configurations override root settings, which override defaults.
- The **`isIgnored(relativePath)`** method provides a simple boolean interface to test any file path against the merged pattern set.
- Negation patterns (e.g., `!important.js`) can be used in custom files to selectively re-include paths excluded by earlier layers.

## Frequently Asked Questions

### What is the default precedence order for ignore patterns?

The **ignore-filter** processes patterns in three stages: first the hard-coded defaults, then the project-root `.understandignore`, and finally the workspace-specific `.understandanything/.understandignore`. Because later additions are processed after earlier ones, workspace patterns have the highest precedence, followed by root patterns, with defaults serving as the fallback.

### Can I un-ignore a file that matches a default pattern?

Yes. By adding a negation pattern (starting with `!`) to your `.understandignore` or workspace-specific ignore file, you can re-include files that would otherwise be excluded by the `DEFAULT_IGNORE_PATTERNS`. For example, `!vendor/important.js` in your workspace ignore file will ensure that specific file is analyzed even if `vendor/` is in the default list.

### Where should I place my custom .understandignore file?

For project-wide exclusions, place `.understandignore` in the repository root. For workspace-specific overrides (such as in a monorepo), create `.understandanything/.understandignore` inside the relevant workspace directory. The filter automatically discovers both locations when `createIgnoreFilter` is invoked with the project root path.

### How does the ignore-filter handle negation patterns?

The underlying `ignore` library supports standard Gitignore-style negation using the `!` prefix. When you include a negation pattern in a custom ignore file, it overrides any preceding positive match from the defaults or earlier configuration files. This allows fine-grained control where you can ignore broad categories (like `*.log`) but carve out exceptions (like `!important.log`) in subsequent layers.