This document outlines all the validation rules enforced by the agent-md linter when writing markdown content. Each rule includes examples of invalid syntax and recommended alternatives.
The agent-md linter enforces AI-friendly markdown standards to ensure content is easily readable and parseable by AI agents. The rules focus on simplicity, clarity, and machine-readability.
Rule ID: no-bold
Severity: Error
Description: Bold text formatting is not allowed for AI agents, except in code blocks.
❌ Invalid - Double asterisks
This is **bold text** that will be rejected.
❌ Invalid - Double underscores
This is __also bold__ and will cause an error.
❌ Invalid - Mixed usage
Both **bold** and __bold__ are prohibited.
✅ Valid - Use plain text
This is important text without bold formatting.
✅ Valid - Use italics for emphasis
This is *italic text* which is allowed.
✅ Valid - Use headings for emphasis
## Important Section
This section contains important information.
✅ Valid - Use code formatting for technical terms
Use `monospace` for technical terms or variable names.
✅ Valid - Bold text is allowed inside code blocks
function example() {
// This **bold** text is allowed in code blocks
console.log("**This bold text is also allowed**");
return __bold__;
}This is a code block with **bold** text that is allowed.
✅ Valid - Bold text is also allowed in inline code
Use `**bold**` and `__bold__` in inline code for emphasis.
✅ Valid - Bold text in table cells is auto-formatted
| Name | Description |
|---|---|
| Item | This has bold text |
| Test | This has italic text |
When formatting markdown, strip_bold_from_cell automatically removes ** and __ markers from table cell content while preserving inline code spans.
**bold** and __bold__ are allowed in both inline code ( ) and fenced code blocks ( ). Bold in table cells is automatically stripped during agent-md fmt.
Bold text creates visual noise for AI agents and doesn't add semantic meaning that can't be conveyed through other means like headings or code formatting. Code blocks are exempt because they preserve original syntax and formatting for programming languages, documentation, and other contexts where bold characters may have specific meaning or be part of the code syntax itself.
Table cells are auto-formatted — bold markers are stripped during agent-md fmt so the resulting table contains plain text. Inline code within table cells and throughout markdown (such as code block: let a = 1;``) is preserved unchanged without formatting modifications, including spaces inside backticks.
Rule ID: simple-tables
Severity: Error
Description: Tables should use simple syntax without complex attributes.
❌ Invalid - Complex table attributes
| Header 1 | Header 2 |
|----------|----------|
| Cell 1 | Cell 2 |
| colspan="2" | Cell 3 |
❌ Invalid - Inline formatting in cells
| Name | Description |
|------|-------------|
| Item | This has **bold** text |
| Test | This has *italic* text |
❌ Invalid - Too many dashes for table separator (should be exactly 3)
| Name | Description |
|------|-------------|
| Test | text |
✅ Valid - Simple table syntax with 3 dash separators
| Name | Description |
|---|---|
| Item | Simple description |
| Test | Another description |
✅ Valid - Alignment colons are automatically removed during agent-md fmt to save tokens
| Name | Description |
|---|---|
| Item | Simple description |
Note: agent-md fmt will convert |:---|:---| to |---|---|.
✅ Valid - Keep tables narrow (≤5 columns)
| Name | Type | Status | Priority | Owner |
|---|---|---|---|---|
| Task | Bug | Open | High | Team |
✅ Valid - Use lists for complex data
- Item 1: Simple description
- Item 2: Another description
- Item 3: Third description
✅ Valid - Use structured formats for complex data
{
"items": [
{"name": "Item 1", "description": "Simple description"},
{"name": "Item 2", "description": "Another description"}
]
}✅ Valid - Empty cells formatted with single space
| Header 1 | Header 2 |
|---|---|
| Item 1 | |
Note: agent-md fmt formats empty table cells with a single space (| |) to normalize table structure cleanly.
✅ Valid - Escaped pipes (\|) for "or" conditions inside table cells
| Option | Syntax |
|---|---|
| Filter | name \| tag \| id |
Note: agent-md fmt preserves escaped pipes (\|) inside table cells without inserting extra spaces or splitting the cell.
Complex tables are difficult for AI agents to parse and can introduce formatting inconsistencies. Simple tables are more reliable for machine processing.
Rule ID: useless-links
Severity: Error
Description: Link text should not be identical to the URL.
# ❌ Invalid - Link text equals URL
Visit [https://example.com](https://example.com) for more info.
# ❌ Invalid - Link text equals URL without protocol
Check out [example.com](https://www.example.com) today.
# ❌ Invalid - Link text equals URL with www
Go to [www.example.com](https://example.com/) now.
✅ Valid - Descriptive link text
Visit [Example Website](https://example.com) for more info.
✅ Valid - Action-oriented link text
[Check out our documentation](https://docs.example.com)
✅ Valid - Contextual link text
See the [API reference](https://api.example.com) for implementation details.
✅ Valid - Plain URLs (when appropriate)
For more information: https://example.com
Links where the text equals the URL provide no additional context and create redundant information. Descriptive link text helps AI agents understand the purpose and destination of links.
Rule ID: no-ascii-graph
Severity: Error
Description: Human-readable ASCII graphs should be replaced with LLM-readable formats. This rule applies to ALL content, including inside code blocks.
Example - Box drawing characters in regular text (invalid)
┌─────────┬─────────┐
│ Name | Value │
├─────────┼─────────┤
│ Item 1 | 100 │
│ Item 2 | 200 │
└─────────┴─────────┘
Example - Box drawing characters in code blocks (invalid)
┌───┐
│ A │
└───┘
Example - Tree structures in regular text (invalid)
root
├── branch1
│ ├── leaf1
│ └── leaf2
└── branch2
└── leaf3
Example - Tree structures in code blocks (invalid)
├── public/
│ ├── pagefind/
│ └── favicon.svg
Example - Flow chart patterns (invalid)
[Start] -> [Process] -> [End]
Example - Progress bars (invalid)
Progress: [████████░░] 80%
Example - Graph-like patterns (invalid)
A --- B --- C
\ | /
D --- E
✅ Valid - Structured CSV
name,value
Item 1,100
Item 2,200
✅ Valid - JSON format
{
"tree": {
"root": {
"branch1": {
"leaf1": {},
"leaf2": {}
},
"branch2": {
"leaf3": {}
}
}
}
}✅ Valid - Mermaid Diagram
flowchart LR
Start --> Process --> End
✅ Valid - Numbered List with Conditions
1. Start: Initialize process
2. Process: Execute main logic
3. End: Finalize and return
✅ Valid - ZON format (Zero Overhead Notation) See: https://github.com/ZON-Format/ZON, https://zonformat.org/.
users:@(3):id,tier
1,premium
3,free
5,pro✅ Valid - Simple progress indicator
Progress: 80% complete
ASCII graphs are visually appealing but difficult for AI agents to parse reliably. Structured formats like JSON, CSV, or Mermaid diagrams provide machine-readable alternatives.
Unlike bold text (which is allowed in code blocks because it may be part of programming language syntax), ASCII graphs in code blocks are still visual patterns that AI agents struggle to interpret. The agent-md linter therefore rejects ASCII graphs even inside code blocks, as they provide no additional semantic value for AI processing.
When you need to represent tree structures, diagrams, or visual hierarchies, use these alternatives:
- JSON for nested data structures
- CSV for tabular data
- Mermaid for flowcharts and diagrams
- Numbered lists with conditions for processes
- Simple text descriptions for progress indicators
Rule ID: heading-structure
Severity: Error
Description: Headings should follow logical hierarchy and not skip levels.
❌ Invalid - Skipping heading levels
# Title
### Subsection (skips H2)
❌ Invalid - Multiple H1 headings
# First Title
# Second Title
❌ Invalid - Inconsistent heading style
## Heading 1
### Heading 2
#### Heading 3
###### Heading 4 (skips H5)
✅ Valid - Sequential heading levels
# Title
## Section 1
### Subsection 1.1
#### Sub-subsection 1.1.1
✅ Valid - Single H1 per document
# Main Title
## Section 1
## Section 2
✅ Valid - Consistent hierarchy
# Document Title
## Overview
## Implementation
### Details
### Examples
## Conclusion
Proper heading structure creates a logical document outline that AI agents can easily navigate and understand.
Rule ID: code-blocks
Severity: Error
Description: Code blocks should specify language when possible, and must always have valid, matching opening and closing fences. Unclosed code blocks are immediately rejected with a syntax error, immediately halting linting and formatting to prevent document corruption.
❌ Invalid - Missing closing fence / Unclosed code block
"```javascript"
function test() {
console.log("unclosed block");
// Missing closing "```" here
❌ Invalid - Unspecified language
"```"
function example() {
return "Hello World";
}
"```"
❌ Invalid - Inline code for multiline content
function example() {
return "Hello World";
}
✅ Valid - Specify language
function example() {
return "Hello World";
}✅ Valid - Use appropriate language
def example():
return "Hello World"✅ Valid - Inline code for short snippets
Use console.log() for debugging.
✅ Valid - When no language is specified, use text
This is a code block without specific language
Note: During agent-md fmt, unlabelled code blocks automatically get text as their default language tag (e.g. ``` becomes ```text), including code fences nested inside list items. Empty list items (e.g. a trailing - line with no content) are removed during formatting.
Specifying language helps AI agents understand the context and apply appropriate parsing rules.
Rule ID: list-formatting
Severity: Error
Description: Lists should be consistent and properly formatted.
❌ Invalid - Mixed list types
1. First item
- Second item
2. Third item
❌ Invalid - Inconsistent spacing
1. First item
2. Second item
3. Third item
❌ Invalid - Empty list items
1. First item
2.
3. Third item
✅ Valid - Consistent ordered list
1. First item
2. Second item
3. Third item
✅ Valid - Consistent unordered list
- First item
- Second item
- Third item
✅ Valid - Nested lists
1. Main item
1.1. Sub item
1.2. Another sub item
2. Second main item
Consistent list formatting improves readability and parsing reliability for AI agents.
Rule ID: no-duplicate-headings
Severity: Warning
Description: Headings with the same content should not appear multiple times in a document.
❌ Invalid - Same heading content at different levels
## Introduction
Some content here
### Introduction
Different content but same heading text
❌ Invalid - Same heading content at same level
## Overview
First overview content
## Overview
Second overview content
❌ Invalid - Multiple identical headings
## Usage
How to use the tool
## Usage
More usage instructions
## Usage
Additional usage notes
✅ Valid - Unique heading content
## Introduction
Some content here
### Getting Started
Different content with unique heading
✅ Valid - More specific headings
## Overview
First overview content
## Detailed Overview
Second overview content
## Quick Reference
Additional reference material
✅ Valid - Numbered or qualified headings
## Usage: Basic Operations
How to use the tool
## Usage: Advanced Features
More usage instructions
## Usage: Troubleshooting
Additional usage notes
✅ Valid - Hierarchical structure
## Usage
### Basic Operations
How to use the tool
### Advanced Features
More usage instructions
### Troubleshooting
Additional usage notes
Duplicate headings create ambiguity for AI agents when navigating and referencing document sections. Unique heading content ensures clear navigation and unambiguous section identification, making it easier for AI agents to understand and process document structure.
Rule ID: single-title
Severity: Error
Description: Documents should have only one top-level heading (H1).
❌ Invalid - Multiple H1 headings
# First Title
Some content here
# Second Title
More content here
❌ Invalid - H1 headings mixed with other levels
# Main Title
## Section
# Another Main Title
✅ Valid - Single H1 heading
# Document Title
## Section 1
Content for section 1
## Section 2
Content for section 2
✅ Valid - Proper hierarchy
# Main Title
## Overview
## Details
### Specific Detail
## Conclusion
Multiple H1 headings create confusion about the document's main title and structure. AI agents rely on a clear document hierarchy, and a single H1 provides an unambiguous entry point for understanding the document's purpose.
Rule ID: space-indentation
Severity: Error
Description: Use at most 2 spaces for indentation in regular text. Code blocks are exempt from this rule.
❌ Invalid - 4 spaces for text indentation
This paragraph is indented with 4 spaces.
It should use 2 spaces or less.
❌ Invalid - Excessive indentation in lists
1. First item
2. Second item with deep indentation
3. Third item
✅ Valid - 2 spaces or fewer for text
This paragraph uses 2 spaces for emphasis.
Second line of the paragraph.
✅ Valid - No indentation for regular text
This paragraph starts at the left margin.
No extra spaces are needed.
✅ Valid - Code blocks are exempt
function example() {
// Code blocks can use proper indentation
// regardless of space count
return true;
}✅ Valid - Indented code blocks preserve formatting
def example():
# Python code uses 4 spaces
# This is intentional and allowed
pass✅ Valid - Tab character for text indentation
This paragraph uses a tab character.
Excessive indentation (more than 2 spaces) in regular text can cause parsing issues and formatting inconsistencies. Code blocks are exempt because they require proper indentation for readability and many programming languages mandate specific indentation styles.
Use the fmt command to automatically convert 4 leading spaces of list item indentation to 2 spaces, and 2 leading tabs to 1 tab:
agent-md fmt path/to/file.mdRule ID: table-trailing-spaces
Severity: Error
Description: Table cells should not have trailing spaces, except for a single optional space.
Invalid - Multiple trailing spaces in table cells
| Name | Description |
|---|---|
| Item | This is an item |
Invalid - Many trailing spaces in cells
| Column 1 | Column 2 | Column 3 |
|---|---|---|
| Value 1 | Value 2 | Value 3 |
Valid - No trailing spaces in cells
| Name | Description |
|---|---|
| Item | This is an item |
Valid - Single trailing space in cells (allowed but not recommended)
| Name | Description |
|---|---|
| Item | This is an item |
Valid - Table separator rows are ignored
| Name | Description |
|---|---|
| Item | This is an item |
Use the fmt command to automatically remove leading and trailing spaces from all table cells:
agent-md fmt path/to/file.mdTrailing spaces in table cells are unnecessary and can cause formatting inconsistencies. They add visual noise without any semantic value and may cause issues with markdown parsers and version control systems.
Rule ID: no-trailing-spaces
Severity: Warning
Description: Trailing spaces at the end of lines are unnecessary and should be removed.
❌ Invalid - Trailing spaces
This line has a trailing space
This line has multiple trailing spaces
✅ Valid - No trailing spaces
This line has no trailing spaces
This line is also clean
Trailing spaces are often invisible to the reader but can cause formatting inconsistencies, bloat the file size, and create unnecessary diffs in version control.
Rule ID: no-hard-tabs
Severity: Warning
Description: Use spaces for indentation instead of hard tabs.
❌ Invalid - Hard tabs
This line starts with a tab.
- List item with a tab.
✅ Valid - Spaces for indentation
This line starts with spaces.
- List item with a space.
Tabs can be rendered inconsistently across different editors and platforms, leading to alignment issues. Spaces ensure consistent rendering everywhere.
Rule ID: blanks-around-headings
Severity: Warning
Description: Headings should be surrounded by blank lines for better readability.
Note: This rule is configurable via .agent-md.json (or .markdownlint.json). If "blanks-around-headings": false is specified, the linter will not enforce blank lines around headings, and the formatter will not auto-add spaces between headings and other content.
❌ Invalid - Missing blank lines
Some paragraph text.
# Heading 1
More paragraph text.
✅ Valid - Blank lines around headings
Some paragraph text.
# Heading 1
More paragraph text.
Proper spacing around headings makes the document structure clearer and visually separates sections, enhancing readability for both humans and AI agents.
Rule ID: first-line-h1
Severity: Warning
Description: The first non-blank line in a document should be a top-level heading (H1).
❌ Invalid - Missing H1 at start
This is an introduction paragraph.
# Main Title
✅ Valid - Starts with H1
# Main Title
This is an introduction paragraph.
Starting a document with an H1 heading immediately establishes its main subject and purpose, making it easier to identify the content's context.
Rule ID: single-trailing-newline
Severity: Warning
Description: Files should end with exactly one single newline character.
❌ Invalid - Missing trailing newline
# Title
Content ends here without a newline
❌ Invalid - Multiple trailing newlines
# Title
Content ends here.
✅ Valid - Single trailing newline
# Title
Content ends here.
<newline>
A single trailing newline is a POSIX standard for text files, ensuring that tools and parsers process the file correctly without missing the last line or complaining about EOF behavior.
Rule ID: no-multiple-blanks
Severity: Warning
Description: Consecutive blank lines should be avoided. Use at most one blank line between content blocks.
❌ Invalid - Triple newlines (two blank lines)
First paragraph.
Second paragraph.
✅ Valid - Double newlines (one blank line)
First paragraph.
Second paragraph.
Multiple consecutive blank lines increase token usage without adding semantic value. They also make document navigation less efficient for AI agents.
When using the agent-md lint command, validation results are returned in JSON format:
{
"valid": false,
"errors": [
{
"line": 3,
"column": 12,
"message": "Bold text is not allowed for AI agents",
"rule": "no-bold"
}
],
"warnings": [
{
"line": 7,
"column": 1,
"message": "Link text should not be the same as the URL - provide meaningful link text",
"rule": "useless-links"
}
]
}- valid: Boolean indicating if the document passes all validation rules
- errors: Array of validation errors that prevent writing
- warnings: Array of warnings that don't prevent writing but should be addressed
- line: Line number where the issue occurs (1-based)
- column: Column number where the issue occurs (1-based)
- message: Human-readable description of the issue
- rule: Internal rule identifier
- Use plain text instead of bold formatting
- Keep tables simple with ≤5 columns and no complex attributes
- Write descriptive link text rather than repeating URLs
- Use structured formats (JSON, CSV, Mermaid) instead of ASCII art
- Maintain proper heading hierarchy without skipping levels
- Specify code block languages when possible
- Format lists consistently with proper spacing and structure
- Avoid duplicate headings with the same content
- Use only one H1 heading per document
- Limit text indentation to 2 spaces or fewer (code blocks exempt)
- Avoid trailing spaces in table cells (0 or 1 space maximum)
- Remove trailing spaces at the end of lines
- Use spaces instead of hard tabs for indentation
- Surround headings with blank lines
- Start documents with an H1 heading
- End files with a single newline character
- Avoid multiple consecutive blank lines
- Minify HTML tags and remove redundant indentation or newlines inside HTML elements
When writing or formatting HTML inside Markdown files, agent-md applies minification rules to reduce token consumption:
- Remove useless spaces, tabs, and newlines inside HTML tags
- Strip redundant indentation from child lines inside HTML blocks
- Merge standalone closing tag lines into the preceding element line
- Preserve original HTML tag names, attribute names, and attribute values verbatim
Input:
<p align="center">
<img src="badge.png" alt="Markdown" />
</p>Formatted output:
<p align="center">
<img src="badge.png" alt="Markdown" /></p>These rules are automatically enforced when using the agent-md write command. The tool will reject content that contains errors and return warnings for style issues.
# Validate content before writing
agent-md lint --content "# Title\nContent with **bold** text"
# Lint file with human-readable output
agent-md lint-file README.md
# Write with automatic validation
agent-md write document.md "# Title\nValid content without bold"When working on repositories with generated files, third-party libraries, or build artifacts (such as target/, dist/, or logs/), configure ignore patterns to prevent unwanted processing.
agent-md automatically loads .markdownlintignore from the current directory and merges its patterns with .gitignore, deduplicating repeated items.
dist/
logs/
target/
Commands such as agent-md list and agent-md fmt <dir> automatically filter out ignored files and directories. To inspect the resolved deduplicated ignore list, run:
agent-md ignore
# Returns: ["dist/", "logs/", "target/", "/target", "temp/", "*.log", "*.tgz", ".antigravitycli"]By following these rules, you ensure your markdown content is optimized for AI agent consumption and processing.