Document Management
Backlog.md treats project documents as first-class citizens. All documents are stored as Markdown files under backlog/docs/, support nested subfolders, a global ID index, and full CLI lifecycle operations.
Creating Documents
# Minimal creation
backlog doc create "API Design Guide"
# Specify document type
backlog doc create "Architecture Decision Description" -t guide
# Create in a subdirectory
backlog doc create "Deployment Manual" -p guides/deployment
After creation, the CLI prints the generated file path, for example backlog/docs/guides/deployment/doc-5 - Deployment Manual.md. The document ID (such as doc-5) is globally unique across the entire backlog/docs/ tree; you can view and update it by ID regardless of which subfolder it lives in.
doc createalso accepts the--plainflag. Creation output is already plain text; the flag is accepted (rather than switching output formats) so that agent invocations that habitually append--plainto every command do not fail with "unknown option".
Subpath Rules
- Paths are always relative to the
backlog/docs/directory; do not write absolute paths. - Multi-level nesting is supported, for example
-p guides/deployment/aws. ..and absolute paths are not allowed; the system rejects attempts to escape the directory.
Updating Documents
# Update document content
backlog doc update doc-5 --content "## Deployment Steps\n\n1. Build image\n2. Push to registry"
# Update title, type, and labels at the same time
backlog doc update doc-5 --title "Production Deployment Manual" -t runbook --tags deploy,aws
# Move to a new subdirectory
backlog doc update doc-5 -p guides/production
backlog doc update uses incremental updates: provide only the fields you want to change; fields you omit keep their original values. For example, if you only pass --title, the document content and path are not affected.
Multi-Line Content and Appending
--content supports \n newline escapes, consistent with task --desc, --plan, and --notes:
backlog doc update doc-5 --content "## Overview\n\nFirst paragraph\nSecond paragraph"
To append a block while preserving existing content, use the repeatable --append-content option. The appended block is separated from the base content by a blank line, and can be combined with --content (the append is placed after the replaced content):
# Append a section to the end of an existing document
backlog doc update doc-5 --append-content "## Appendix\n\nSupplementary notes"
# Replace then append
backlog doc update doc-5 --content "New content" --append-content "Appendix section"
The MCP document_update tool provides a matching appendContent parameter.
Listing Documents
backlog doc list
In TTY terminals, this command opens a dual-pane interactive browser: the left pane lists Documents (N) and the right pane renders the Markdown content of the selected document in real time. ← / → switch focus between panes, ↑ / ↓ (or j / k) navigate or scroll within the current pane, Enter opens the full viewer, ? opens the help popup, and q exits. The active pane border is highlighted in yellow and returns to normal when focus is lost. --plain, --json, and non-TTY environments still output a list text, unchanged.
The command scans backlog/docs/ and all subdirectories, printing the ID, title, type, and path of every document. When there are many documents, combine paging windows and fuzzy search:
# Paging window: first 20 / next page / total count only
backlog doc list --max-count 20
backlog doc list --max-count 20 --skip 20
backlog doc list --count
backlog search "deployment"
The paging options (--max-count / --skip / --count) have the same semantics as the eight list commands such as search and task list; see the "List Paging" section in Search & Sequences. Search covers tasks, documents, and decision records (memo and Wiki results are in the Web global search).
Viewing Documents
# Interactive view (TUI popup renders Markdown)
backlog doc view doc-5
# Plain-text output (good for AI agents or scripts)
backlog doc view doc-5 --plain
The --plain flag outputs raw Markdown content plus frontmatter metadata, making it easy to read in pipelines or chat windows.
Reference Forms and Ambiguity Handling
doc view accepts three reference forms and tries them in order:
| Form | Example | Description |
|---|---|---|
| Bare ID | doc-5 |
Default form; directly resolves when the ID is unique across the backlog/docs/ tree |
| Document-relative path | migration/doc-14 |
Omit the .md extension; also supports folder/ID-filename form |
| Filename title slug | Deployment Manual |
The title part after ID - in the filename, case-insensitive |
Identity resolution is fail-closed: when the same ID appears in different subdirectories (for example guide/doc-1 - A.md and migration/doc-1 - B.md), the bare ID immediately fails and lists all candidate paths (exit code 1) rather than picking one. The error message includes runnable disambiguation suggestions—folder/ID when the candidate is unique, otherwise the full path (auto-quoted when it contains spaces). Path forms reject .. escapes and drive-letter prefixes; matching multiple files also errors.
Related behaviors:
- Documents or decisions that lack an
idfrontmatter still appear in lists but cannot be addressed by ID. - The Web interface shows a dedicated hint for ambiguous IDs (server returns HTTP 409 plus the candidate list) and does not fall back to stale cached entries.
- MCP returns an
AMBIGUOUS_IDerror and includes candidate paths in the structured content.
Backlinks
The document page (right pane of the CLI doc view interactive browser, and the Web document detail page) displays a backlinks list showing which tasks, documents, decisions, or Wiki pages reference the current document:
- The index is built on the client (
buildBacklinkIndex) and refreshes live as content changes; it never writes back to files. - Each backlink shows the source type icon, title, and ID; click to open the source in the current view.
- Sources that match multiple IDs are collapsed into a dropdown selector to avoid drowning the page in long lists.
Backlinks are a read-only navigation aid and do not affect document content or dependency resolution.
Live SQL Query Blocks
Documents (shared with tasks, decisions, memos, and Wiki pages) can embed sqlite-query and duckdb-query fenced code blocks. The Web reading view renders these blocks as live read-only query results against the real database file (the editing view still shows the original source):
```sqlite-query
source: backlog/databases/shop.sqlite
view: table
sql: |
SELECT product, price, stock
FROM inventory
ORDER BY price DESC
```
Block fields (minimal YAML subset):
| Field | Required | Default | Description |
|---|---|---|---|
source |
Yes | — | Project-relative path to the database (no leading /, absolute paths, or .. escapes). SQLite supports .sqlite / .sqlite3 / .db; DuckDB supports .duckdb (later expanded to .csv / .xlsx). |
sql |
Yes | — | Query statement; must be read-only (must start with SELECT or WITH … SELECT; write keywords are rejected, and a read-only handle is used as a physical safeguard). |
view |
No | table |
Display mode: table (grid), list (vertical key-value list), value (first row and first cell only), echarts (render a chart directly; see Chart Blocks). |
refresh |
No | manual |
Manual refresh only; automatic / scheduled refresh is not supported. |
By default results are limited to 500 rows; the cap is configured by query_max_rows in config.yml. If the limit is exceeded, the block shows a truncation notice. Pagination can be enabled in the block header; paging is pushed down to the engine via LIMIT / OFFSET and is not constrained by the preview cap. The block header provides four actions: Refresh (rerun against the current disk state), Show / Hide Query (expand/collapse the read-only source + SQL, collapsed by default), Copy Markdown (serialize the current results as a GFM table to the clipboard), and Export CSV (rerun on the server and generate a CSV saved to the user's chosen location). If the safe-path check fails or the query errors, the error is rendered inside the block and does not affect the rest of the page.
Query blocks can also render charts directly (view: echarts), or be referenced by standalone charts via fromQuery; see Chart Blocks for the full flowchart and data-chart usage.
Document Organization Recommendations
As the project evolves, files under backlog/docs/ will grow. The following directory structure is recommended to keep things clear:
backlog/docs/
├── readme.md # docs directory overview
├── api/
│ ├── doc-1 - REST-Standards.md
│ └── doc-2 - GraphQL-Schema.md
├── guides/
│ ├── doc-3 - Local-Development.md
│ └── doc-4 - Deployment-Process.md
└── runbooks/
└── doc-5 - Troubleshooting.md
Tip:
backlog doc listandbacklog doc viewautomatically traverse all subdirectories. When document IDs are globally unique, you only need to remember the ID; if the same ID exists in different subdirectories, disambiguate withfolder/ID(for examplemigration/doc-14) or the title slug. When ambiguous, the command lists all candidate paths.