Migrating into commission
You will be able to move existing work into commission from Jira, Linear, or a markdown board — knowing before you start exactly what carries over, what does not, and when to stop importing.
Audience: anyone adopting commission on a project that already has a backlog. Assumes: planning a task graph.
This page is about moving in. If Commission has to keep coexisting with a tracker that stays the system of record, you want interop instead — that is a different decision with different consequences.
Decide first: import, or bridge?
| import | bridge | |
|---|---|---|
| what it is | a one-time move; commission becomes the truth | ongoing sync; the other system stays the truth |
| how much | ideally everything that is still real | a deliberate subset, bound explicitly |
| how long | until it is done, then stop | as long as the other system exists |
| covered by | this page | interop |
The commonest adoption mistake is importing a backlog and then leaving the sync running “just in case”. Two systems that both think they are authoritative is the exact failure commission exists to prevent, and it is worse than either system alone.
What carries over, and what does not
The same table holds for every source, because it is a property of commission’s data model rather than of any adapter.
| carries over | does not |
|---|---|
| title, description, status, priority | comments and discussion threads |
| acceptance-criteria checklists → criteria | attachments and images |
| blocking links → dependencies | story points, estimates, and velocity |
components / labels → touches | sprints as containers (sprint is a field, not a parent) |
| epic membership → parent task | workflow states beyond commission’s five |
| a link back to the original issue | custom fields Commission was not told about |
| assignee (as a name) | watchers, followers, notification rules |
Two of those are deliberate omissions rather than gaps, and it is worth knowing that before you go looking for the flag:
- There is no estimation. No points, no velocity, no burndown. Commission tracks what is true and what is finished, not how long somebody guessed it would take.
- There are five statuses and no way to add a sixth. A workflow with
“Triaged”, “Groomed”, and “Awaiting QA” collapses into
open,in_progress, andin_review. If those distinctions carry real meaning for you, they belong in the system that already models them — bridge, do not import.
Comments are the loss people feel most. The mitigation is to write the decisions that mattered into notes as you go, which is more useful than the comment thread was anyway:
commission note myapp-2 -m "carried over from RTB-543: we chose the webhook over polling because the vendor rate-limits at 60/min"From Jira
export JIRA_BASE_URL=https://acme.atlassian.net
export JIRA_EMAIL=you@acme.com
export JIRA_API_TOKEN=...
commission import jira --slug work
commission import jira --jql "project = PAY AND sprint in openSprints()"Import a slice, not the whole instance. The default query is your open issues plus the last fortnight of done ones, which is a sensible first pass; a JQL that returns eight hundred tickets produces a graph nobody will read.
Jira-specific mapping on top of the general table:
- “Blocks” links become commission dependencies.
- Priorities map to
p0–p3. - Components become
toucheslabels, so parallel dispatch avoids collisions between tickets in the same area. - Due date, sprint, rank, and severity import when their custom-field ids are
configured — see
integrations.jira.fieldsin worked configurations. - Every task links back to its issue.
No API token? If your agent has an Atlassian MCP connector, run the JQL there, save the JSON, and import offline:
commission import jira --from-file saved-search.jsonBoth the REST v3 envelope (issues: [...]) and the MCP/Rovo envelope
(issues: { nodes: [...] }) are accepted.
Re-running an import upserts by external key rather than duplicating, so a partial first pass is safe to redo.
From Linear
There is no Linear adapter, and this page will not pretend otherwise. Linear’s export is good enough that the honest path is a two-step:
- Export from Linear — CSV or the GraphQL API, whichever you already have.
- Convert it to an apply document and land it.
The conversion is a genuinely reasonable thing to hand to an agent, because the target format is small and the result is checkable before it is written:
commission apply -f plan.json --dry-run
commission apply -f plan.jsonMap Linear’s fields as follows, which is the same mapping the Jira adapter uses:
| Linear | apply field |
|---|---|
| issue title / description | title, body |
issue identifier (ENG-214) | key, and a links entry back to the issue |
| “blocks” relations | deps |
| project or epic | parent |
| labels | touches |
| priority (0–4) | priority (0–3; Linear’s “no priority” is commission’s default) |
| sub-issue checklists | criteria |
| state | status — collapsed to commission’s five |
Landing it is one transaction: a document that references a missing dependency creates nothing, so an imperfect conversion fails loudly instead of leaving half a backlog behind.
From a markdown board
If your backlog is a directory of markdown — epics, stories, a COMPLETE.md —
there is an adapter for exactly that shape:
commission import mega-docs ./mega-docsIt expects backlog/epics/EPIC-XXX.md and backlog/stories/TASK-XXX.md, reads
## Status and ## Parent epic headings, turns acceptance-criteria checklists
into criteria, pulls PR #N references out of the completion board into
evidence, and uses README.md as the project vision. It upserts by external key,
so re-running syncs rather than duplicating.
If your markdown does not have that shape — and most does not — do not fight the
adapter. Convert to an apply document, the same as Linear. A directory of
markdown is a much easier thing for an agent to read than a tracker’s API, and
--dry-run tells you whether it understood.
The one thing not to do is keep the markdown board afterwards. Commission’s whole
premise is that status lives in one place; a STATUS.md that is regenerated
from Commission is fine (commission export writes one, with a do-not-edit header), and a
STATUS.md that anybody edits by hand is the drift you just paid to remove.
commission export --project myapp > STATUS.mdAfter the import
commission board --project myapp
commission doctor --project myapp
commission ready --project myappdoctor is the one to actually read. It checks that the dependency graph is
acyclic and references real tasks, that links resolve, that bindings are covered
by the project’s declared integrations, and that the search index covers every
task. An import is exactly the moment those things break.
Then prune. An imported backlog always contains work nobody will do, and it is much cheaper to cancel it now, with a reason, than to have it sit on the board for a year:
commission cancel myapp-3 -m "imported from RTB-88; superseded by the v2 API and nobody has asked in eight months"When to stop importing
Stop when the work that is live is in commission. Not when the backlog is empty — a backlog is never empty, and archaeology is not migration.
A useful test: if a ticket has not been touched in six months and nobody would notice it disappearing, it does not need to exist in two systems. Leave it where it is. The tracker you are leaving is a perfectly good archive.
The whole sequence
commission import mega-docs ./mega-docs
commission board --project myapp
commission doctor --project myapp
commission ready --project myapp
commission export --project myapp > STATUS.mdEvery command on this page is executed by tests/docs.test.ts against a scratch
database, except those needing live Jira credentials, which are checked against
the command tree instead.
Related
- Interop — coexisting with a tracker that stays the source of truth.
- Planning a task graph — the apply document you will be writing.
- Apply reference — every field.
Part of Guides.
This page is docs/guides/migration.md in the Commission
repository, rendered in place — the site keeps no copy of it. The repository is private, so there is no edit link to follow.