Core Concepts
The vocabulary and data model behind every backlog command.
| Concept | What it is |
|---|---|
| Workspace | A directory containing backlog.db and config.toml. Created by backlog init. |
| Project | A named grouping of tasks, identified by a short alias. Optionally linked to a repo_path. |
| Task | The unit of work. Has a type, status, priority, and actor. |
| Plan | A versioned markdown document on a task. Every edit creates an immutable version. |
| Comment | A timestamped, actor-attributed note on a task. Append-only. |
| Label | A per-project tag that can be attached to tasks for filtering. |
| Actor | Who performed an action. Format: kind:name where kind is human or ai. |
| Profile | A named pointer to a workspace directory, stored in ~/.config/backlog/config.toml. |
Workspace
A workspace is a directory that contains a backlog.db SQLite file. All data for all projects in that workspace (tasks, plans, docs, comments, memory, labels, attachments, activity) lives in that single file.
Created with backlog init. Two files are written:
| File | Purpose |
|---|---|
backlog.db | SQLite database (WAL mode). Contains everything. Commit this to your repo. |
config.toml | Local workspace settings (default actor, project, output format). |
A backlog.json project manifest is not created by init. It's an optional, hand-authored file listing projects; backlog sync reads it and creates any that don't exist yet in the database (one-way, manifest → DB, never deletes). Commit it alongside backlog.db if you want project definitions tracked in plain text.
DB resolution order
When you run a command, the database is located by the first match in this chain:
--db <path>flag$BACKLOG_DBenvironment variable--profile <name>flag- Default profile from
~/.config/backlog/config.toml
There is no automatic search of the current directory or its parents. If nothing in the chain resolves, the command errors with no backlog workspace found.
$BACKLOG_DB: it bypasses directory walking and makes the path explicit regardless of where the process starts.
Profile
A profile is a named pointer to a workspace directory, registered in ~/.config/backlog/config.toml. Profiles let you switch between workspaces without typing paths.
backlog profile add work --path ~/projects/work/.backlog
backlog profile set-default work # use this workspace by default
backlog task list --profile personal # use a different workspace for one command
backlog profile clear-default # remove the active default
Default workspaces (created by backlog init without --path) are placed at ~/.backlog/<profile-name>/. The default profile name is default.
Project
A project groups tasks within a workspace. It has a human-readable name and a short alias, the alias is what you type in every -p / --project flag.
- Alias constraints: lowercase alphanumeric with optional hyphens, 1–64 characters. E.g.
api,web-frontend,security-2026. - Optional
repo_path: filesystem path to the source repository. - Projects can be archived (hidden from lists) without deleting their tasks.
Set a default project so -p can be omitted:
backlog project set-default api
backlog task list # implicitly uses api
backlog project current # shows the active default
backlog project clear-default
Task
The primary unit of work. Every task belongs to a project and carries:
| Field | Values |
|---|---|
| Ref | TASK-N: per-workspace sequential integer. Also addressable by bare integer or full ULID. |
| Type | task · bug · issue · improvement · feature · vulnerability · chore · spike |
| Status | todo (default) · doing · done |
| Priority | P1–P5. P1 is critical/highest. P3 is default. |
| Actor | kind:name of the creator, attributed at the DB level. |
| Assignee | Optional free-text name of who is responsible. |
| Source | Origin system, e.g. semgrep, pentest-2026. |
| External ref | URL or external ticket ID for cross-referencing. |
Status lifecycle
todo → doing → done
↑___________|
All transitions are valid in any direction. Use backlog task move <id> --status <status>.
Priority scale
| Value | Meaning |
|---|---|
| P1 | Critical: drop everything |
| P2 | High: next sprint |
| P3 | Normal: default |
| P4 | Low: when time permits |
| P5 | Backlog: nice to have |
Plan
A versioned markdown document attached to a task. Plans capture implementation plans, remediation steps, or any structured text that may evolve over time.
The versioning model: every call to backlog plan update creates a new immutable plan_versions row. The plan record tracks the current version number. Old versions are never modified or deleted. backlog plan history <plan-id> returns the full list.
| Ver | Title | Actor | Note |
|---|---|---|---|
| v1 | Initial remediation plan | ai:claude-code | — |
| v2 | Remediation plan (revised) | human:alice | added key rotation step |
| v3 | Remediation plan (final) | human:alice | simplified step 3 per review |
Read a specific version: backlog plan show <plan-id> --version 1.
Actor
An actor is a kind:name pair that attributes every write operation. Kind is either human or ai.
| Example | Meaning |
|---|---|
human:alice | Alice the engineer |
ai:claude-code | Claude Code agent |
ai:semgrep | Semgrep scanner (automated import) |
human:ci | CI system acting on behalf of a human workflow |
Every task, plan version, doc version, comment, memory entry, and activity log event records the actor. This allows filtering: backlog task list --actor-kind ai or backlog task list --actor-name semgrep.
The actor is resolved at runtime from the --as flag, workspace config, global config, or $USER env var, in that order. If none are set it defaults to human:$USER.
Label
A per-project tag that can be attached to tasks. Labels have a name and an optional hex color. They are scoped to a project: a label named security in project api is distinct from one in project web.
backlog label create --project api "security" --color "#e03e3e"
backlog label attach --task TASK-1 security
backlog task list --label security
Doc
A versioned markdown document attached to a project (not a task). Docs are used for longer-form project-level content: architecture overviews, runbooks, design documents, ADRs.
The versioning model is identical to plans: each update creates a new immutable version row. Docs also support an append operation that creates a new version concatenating old content with new content.
backlog web or the API directly.
Memory
A free-form note attached to a project. Unlike docs, memory entries are not versioned: they are mutable records with a body and optional comma-separated tags.
Memory is intended for short-lived context: decisions, assumptions, meeting notes, design rationale. AI agents working on a project can read and write memory entries via the MCP memory_add and memory_list tools.
backlog memory add --project api --body "Auth team decision: JWT TTL = 15min" --tags "decision,auth"
backlog memory list --project api --tag decision
ULID vs TASK-N
Every entity (task, plan, doc, comment, memory, label, attachment) uses a ULID as its primary key, a 26-character lexicographically sortable identifier. Tasks additionally have a human-readable sequential reference.
All three formats are accepted wherever a task ID is expected:
| Format | Example | Notes |
|---|---|---|
| Sequential ref | TASK-5 | Canonical. Use in messages, comments, PRs. |
| Bare integer | 5 | Shorthand. Resolves to the same task. |
| Full ULID | 01KR4JA4754H... | Useful when chaining JSON output between commands. |
| ULID prefix | 01KR4JA4 | The 8-char prefix shown in table output. |
Plan IDs, doc IDs, memory IDs, and attachment IDs are always ULIDs. There is no sequential N form for those entities.
Activity log
An append-only event log that records every write operation across the workspace. Each event stores:
- entity: the kind of entity affected (
task,plan,doc,comment,memory,project,label,attachment) - entity_id: the ULID of the affected entity
- action: the operation performed (
created,updated,status_changed,archived,deleted, etc.) - actor:
kind:nameof who performed the operation - summary: a human-readable description of the change
- project_id: the project the event belongs to
The activity log is never pruned. Query it with backlog activity or view the Activity page in the web UI.