# `.dlm/ignore` reference
A plain-text file that lives beside `.dlm/training.yaml` and carries
one ignore pattern per line. Same anchor, different file — a repo
can have either, both, or neither.
Use `.dlm/ignore` when you want drive-by exclusions without writing
YAML. A three-line file is legal and common.
!!! info "`.dlm` (file) vs `.dlm/` (directory) — two different things"
Both `.dlm` shapes live in this project and it's worth naming the
distinction once:
- `mydoc.dlm` — **a file** with a `.dlm` extension. The document
itself, with YAML frontmatter + markdown body. Plural: users own
many `mydoc.dlm` files, one per trainable corpus.
- `.dlm/` — **a directory** named literally `.dlm`. Lives inside a
codebase or data tree and holds `training.yaml` + `ignore` +
(when auto-scaffolded by `dlm train
`) a `corpus.dlm` file.
The two share a name but not a namespace. When `dlm train `
auto-scaffolds, it creates a `.dlm/` directory inside `` and
places `corpus.dlm` inside it — so a single tree can end up with
`/.dlm/corpus.dlm`.
## Example
```
# /.dlm/ignore
# Comments start with #. Blank lines are skipped.
*.min.js
**/fixtures/huge_*.json
docs/generated/
# Negate to re-include a file an earlier pattern excluded:
!docs/generated/README.md
# Trailing / = directory-only
build/
# Leading / = anchored to this .dlm/'s parent (not any ancestor)
/scripts/local-dev.sh
```
## Grammar — supported
| Syntax | Meaning |
|---|---|
| `# comment` | Line comment. Leading whitespace allowed before `#`. |
| blank line | Skipped. |
| `pattern` | Exclude match. |
| `!pattern` | Re-include (negation) what an earlier pattern excluded. |
| `pattern/` | Directory-only — match only dirs, or paths under a dir that matches. |
| `/pattern` | Anchored — match only at the `.dlm/`'s parent (not any ancestor). |
| `**` | Globstar — matches zero or more path segments. |
| `*` | Matches one path segment (non-`/`). |
| `?` | Matches one character (non-`/`). |
## Grammar — NOT supported
The parser is a **strict subset** of `.gitignore`. Users coming from
git may expect these and be surprised:
| Missing feature | Workaround |
|---|---|
| Character classes `[abc]` | List patterns separately: `a.py`, `b.py`, `c.py`. |
| Backslash escapes | Avoid literal `*`, `?`, `#`, `!`, `/` at the start of a pattern; rename files if you must. |
| Whitespace-escape with backslash | File names with trailing whitespace aren't supportable. |
If you need any of the above, fall back to `training.yaml`'s
`exclude:` list — same glob grammar as `include:`, same fnmatch-style
semantics as elsewhere in dlm.
## Semantics — last-match-wins
Rules are evaluated top-to-bottom within a single file, and outer
anchors first across the ancestor chain. For each candidate file,
the **last** rule to match determines the verdict:
- Match a non-negation rule → excluded.
- Match a `!negation` rule → re-included.
- No match → pass through (exclude/include resolution falls to the
outer layers — parent directive, defaults, `training.yaml`).
This mirrors `.gitignore` exactly, so intuition transfers.
## Worked example
Tree:
```
repo/
.dlm/
ignore *.log\n!special.log\n
debug.log
special.log
docs/
.dlm/
ignore !*.log\n
docs-only.log
```
Verdict (parent directive: `include: ['**/*']`):
| File | Outcome | Why |
|---|---|---|
| `repo/debug.log` | excluded | Matches `*.log`, no later rule reopens it. |
| `repo/special.log` | included | `*.log` excludes, `!special.log` re-includes. |
| `repo/docs/docs-only.log` | included | Parent `*.log` excludes; `docs/.dlm/ignore`'s `!*.log` re-includes for this subtree. |
## Error tolerance
Malformed lines log one WARN and are dropped — a typo in one line
never fails the walk. Bare `!` or bare `/` (no pattern after the
sigil) are treated as malformed.
## Relationship with `.dlm/training.yaml`
At the same `.dlm/` anchor, both files coexist. Their exclude rules
union. Because `.dlm/ignore` is evaluated **after**
`training.yaml.exclude` at the same anchor, a `.dlm/ignore`
`!negation` can re-include a file that `training.yaml` would
otherwise drop. (Reason: `.gitignore` users expect ignore-file rules
to be the final word at their anchor.)