documentlanguagemodel Public
.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 <dir>`) a `corpus.dlm` file.
The two share a name but not a namespace. When `dlm train <dir>`
auto-scaffolds, it creates a `.dlm/` directory inside `<dir>` and
places `corpus.dlm` inside it — so a single tree can end up with
`<dir>/.dlm/corpus.dlm`.
Example
# <repo-root>/.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
!negationrule → 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.)
View source
| 1 | # `.dlm/ignore` reference |
| 2 | |
| 3 | A plain-text file that lives beside `.dlm/training.yaml` and carries |
| 4 | one ignore pattern per line. Same anchor, different file — a repo |
| 5 | can have either, both, or neither. |
| 6 | |
| 7 | Use `.dlm/ignore` when you want drive-by exclusions without writing |
| 8 | YAML. A three-line file is legal and common. |
| 9 | |
| 10 | !!! info "`.dlm` (file) vs `.dlm/` (directory) — two different things" |
| 11 | Both `.dlm` shapes live in this project and it's worth naming the |
| 12 | distinction once: |
| 13 | |
| 14 | - `mydoc.dlm` — **a file** with a `.dlm` extension. The document |
| 15 | itself, with YAML frontmatter + markdown body. Plural: users own |
| 16 | many `mydoc.dlm` files, one per trainable corpus. |
| 17 | - `.dlm/` — **a directory** named literally `.dlm`. Lives inside a |
| 18 | codebase or data tree and holds `training.yaml` + `ignore` + |
| 19 | (when auto-scaffolded by `dlm train <dir>`) a `corpus.dlm` file. |
| 20 | |
| 21 | The two share a name but not a namespace. When `dlm train <dir>` |
| 22 | auto-scaffolds, it creates a `.dlm/` directory inside `<dir>` and |
| 23 | places `corpus.dlm` inside it — so a single tree can end up with |
| 24 | `<dir>/.dlm/corpus.dlm`. |
| 25 | |
| 26 | ## Example |
| 27 | |
| 28 | ``` |
| 29 | # <repo-root>/.dlm/ignore |
| 30 | # Comments start with #. Blank lines are skipped. |
| 31 | |
| 32 | *.min.js |
| 33 | **/fixtures/huge_*.json |
| 34 | docs/generated/ |
| 35 | |
| 36 | # Negate to re-include a file an earlier pattern excluded: |
| 37 | !docs/generated/README.md |
| 38 | |
| 39 | # Trailing / = directory-only |
| 40 | build/ |
| 41 | |
| 42 | # Leading / = anchored to this .dlm/'s parent (not any ancestor) |
| 43 | /scripts/local-dev.sh |
| 44 | ``` |
| 45 | |
| 46 | ## Grammar — supported |
| 47 | |
| 48 | | Syntax | Meaning | |
| 49 | |---|---| |
| 50 | | `# comment` | Line comment. Leading whitespace allowed before `#`. | |
| 51 | | blank line | Skipped. | |
| 52 | | `pattern` | Exclude match. | |
| 53 | | `!pattern` | Re-include (negation) what an earlier pattern excluded. | |
| 54 | | `pattern/` | Directory-only — match only dirs, or paths under a dir that matches. | |
| 55 | | `/pattern` | Anchored — match only at the `.dlm/`'s parent (not any ancestor). | |
| 56 | | `**` | Globstar — matches zero or more path segments. | |
| 57 | | `*` | Matches one path segment (non-`/`). | |
| 58 | | `?` | Matches one character (non-`/`). | |
| 59 | |
| 60 | ## Grammar — NOT supported |
| 61 | |
| 62 | The parser is a **strict subset** of `.gitignore`. Users coming from |
| 63 | git may expect these and be surprised: |
| 64 | |
| 65 | | Missing feature | Workaround | |
| 66 | |---|---| |
| 67 | | Character classes `[abc]` | List patterns separately: `a.py`, `b.py`, `c.py`. | |
| 68 | | Backslash escapes | Avoid literal `*`, `?`, `#`, `!`, `/` at the start of a pattern; rename files if you must. | |
| 69 | | Whitespace-escape with backslash | File names with trailing whitespace aren't supportable. | |
| 70 | |
| 71 | If you need any of the above, fall back to `training.yaml`'s |
| 72 | `exclude:` list — same glob grammar as `include:`, same fnmatch-style |
| 73 | semantics as elsewhere in dlm. |
| 74 | |
| 75 | ## Semantics — last-match-wins |
| 76 | |
| 77 | Rules are evaluated top-to-bottom within a single file, and outer |
| 78 | anchors first across the ancestor chain. For each candidate file, |
| 79 | the **last** rule to match determines the verdict: |
| 80 | |
| 81 | - Match a non-negation rule → excluded. |
| 82 | - Match a `!negation` rule → re-included. |
| 83 | - No match → pass through (exclude/include resolution falls to the |
| 84 | outer layers — parent directive, defaults, `training.yaml`). |
| 85 | |
| 86 | This mirrors `.gitignore` exactly, so intuition transfers. |
| 87 | |
| 88 | ## Worked example |
| 89 | |
| 90 | Tree: |
| 91 | |
| 92 | ``` |
| 93 | repo/ |
| 94 | .dlm/ |
| 95 | ignore *.log\n!special.log\n |
| 96 | debug.log |
| 97 | special.log |
| 98 | docs/ |
| 99 | .dlm/ |
| 100 | ignore !*.log\n |
| 101 | docs-only.log |
| 102 | ``` |
| 103 | |
| 104 | Verdict (parent directive: `include: ['**/*']`): |
| 105 | |
| 106 | | File | Outcome | Why | |
| 107 | |---|---|---| |
| 108 | | `repo/debug.log` | excluded | Matches `*.log`, no later rule reopens it. | |
| 109 | | `repo/special.log` | included | `*.log` excludes, `!special.log` re-includes. | |
| 110 | | `repo/docs/docs-only.log` | included | Parent `*.log` excludes; `docs/.dlm/ignore`'s `!*.log` re-includes for this subtree. | |
| 111 | |
| 112 | ## Error tolerance |
| 113 | |
| 114 | Malformed lines log one WARN and are dropped — a typo in one line |
| 115 | never fails the walk. Bare `!` or bare `/` (no pattern after the |
| 116 | sigil) are treated as malformed. |
| 117 | |
| 118 | ## Relationship with `.dlm/training.yaml` |
| 119 | |
| 120 | At the same `.dlm/` anchor, both files coexist. Their exclude rules |
| 121 | union. Because `.dlm/ignore` is evaluated **after** |
| 122 | `training.yaml.exclude` at the same anchor, a `.dlm/ignore` |
| 123 | `!negation` can re-include a file that `training.yaml` would |
| 124 | otherwise drop. (Reason: `.gitignore` users expect ignore-file rules |
| 125 | to be the final word at their anchor.) |