Skip to content
commission

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?

importbridge
what it isa one-time move; commission becomes the truthongoing sync; the other system stays the truth
how muchideally everything that is still reala deliberate subset, bound explicitly
how longuntil it is done, then stopas long as the other system exists
covered bythis pageinterop

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 overdoes not
title, description, status, prioritycomments and discussion threads
acceptance-criteria checklists → criteriaattachments and images
blocking links → dependenciesstory points, estimates, and velocity
components / labels → touchessprints as containers (sprint is a field, not a parent)
epic membership → parent taskworkflow states beyond commission’s five
a link back to the original issuecustom 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, and in_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 p0p3.
  • Components become touches labels, 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.fields in 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.json

Both 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:

  1. Export from Linear — CSV or the GraphQL API, whichever you already have.
  2. 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.json

Map Linear’s fields as follows, which is the same mapping the Jira adapter uses:

Linearapply field
issue title / descriptiontitle, body
issue identifier (ENG-214)key, and a links entry back to the issue
“blocks” relationsdeps
project or epicparent
labelstouches
priority (0–4)priority (0–3; Linear’s “no priority” is commission’s default)
sub-issue checklistscriteria
statestatus — 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-docs

It 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.md

After the import

commission board --project myapp
commission doctor --project myapp
commission ready --project myapp

doctor 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.md

Every 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.


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.