# MD061 - Forbidden terms
Aliases: `forbidden-terms`
## What this rule does
Detects configurable forbidden terms in your markdown files. This can include warning comments (TODO, FIXME, XXX, HACK), profanity, deprecated terminology, or any other words/phrases you want to flag.
By default, this rule has no terms configured and does nothing until you specify which terms to detect.
## Why this matters
- Flag incomplete work (TODO, FIXME comments)
- Enforce language policies (profanity, inappropriate content)
- Maintain terminology standards (deprecated terms, brand guidelines)
- Track items that need attention before publication
## Configuration
By default, this rule has an empty terms list and does nothing. Configure the terms you want to detect:
```toml
[MD061]
terms = ["TODO", "FIXME", "XXX", "HACK"] # Terms to detect (default: empty)
case-sensitive = true # Exact case matching (default)
```
### Options
| `terms` | array of strings | `[]` | List of forbidden terms to detect. Rule does nothing until configured. |
| `case-sensitive` | boolean | `true` | When `true`, only exact case matches (default). When `false`, matches regardless of case (`todo`, `TODO`, `Todo` all match). |
### Example configurations
**Warning comments (TODO/FIXME):**
```toml
[MD061]
terms = ["TODO", "FIXME", "XXX", "HACK"]
```
**Case-insensitive matching:**
```toml
[MD061]
terms = ["TODO", "FIXME"]
case-sensitive = false # Matches todo, TODO, Todo, etc.
```
**Custom terms for your project:**
```toml
[MD061]
terms = ["REVIEW", "DEPRECATED", "SECURITY"]
```
**Language/content policies:**
```toml
[MD061]
terms = ["damn", "hell"]
case-sensitive = false
```
## Examples
With `terms = ["TODO", "FIXME"]`:
### Flagged
```markdown
# Project Documentation
TODO: Add installation instructions
This section needs work. FIXME: clarify the examples
```
### Not flagged
```markdown
# Project Documentation
## Installation
Follow these steps to install the project.
## Examples
The following examples demonstrate usage.
```
### Skipped contexts
The rule automatically skips forbidden terms in these contexts:
**Code blocks (fenced):**
```markdown
```python
# TODO: This is in a code block, not flagged
def example():
pass
```
```
**Code blocks (indented):**
```markdown
# This is indented code, not flagged
TODO: implement this
```
**Inline code:**
```markdown
Use the `TODO` marker in your code comments.
```
**Frontmatter:**
```markdown
---
title: TODO Application Guide
status: draft
---
```
## Word boundary matching
The rule uses word boundary matching to avoid false positives:
| `TODO: fix this` | Yes | Word boundary before colon |
| `TODO fix this` | Yes | Word boundary (space) |
| `(TODO)` | Yes | Word boundary (parentheses) |
| `TODOMORROW` | No | Part of a larger word |
| `mytodo` | No | Part of a larger word |
## No automatic fix
This rule reports forbidden terms but does not provide automatic fixes. Addressing flagged terms requires human judgment about whether removal, replacement, or resolution is appropriate.
## Rationale
This rule is inspired by ESLint's `no-warning-comments` but generalized for any forbidden terms. This approach:
- Single configurable rule instead of separate rules for each term
- Users define their own project-specific terms
- No-op default that doesn't create noise until configured
- Supports both warning comments and content policy enforcement
## Related rules
- [MD044](md044.md) - Proper names (also uses configurable term detection)