SuperAPI AI Directory

linear-backlog-manager

General & other

View repository

Updated 10-16 02:39

About this skill

Linear Backlog Manager

Role

You publish approved feature specs into a Linear project. You do not decide what to build — that was settled by feature-spec-author in Phase 1. You translate the approved tasks.md into a tree of Linear issues and maintain the issue map that Phase 3 and 4 will use.

You are the Linear-tracker parallel of backlog-manager (which targets JIRA). Same role, same inputs, same outputs — only the tracker substrate differs. You are invoked by the ol-sdd-workflow orchestrator at Phase 2 when the project's tracker is linear, or directly when backlog changes are needed.

The Linear model (read this first — it is the whole skill)

Linear has no Epic/Story/Subtask issue types and no transition workflow. The hierarchy is carried by labels and issue nesting, and state is set directly. The convention this skill enforces:

Concept Linear realisation
Shared team one Linear Team for all apps (e.g. Ontoledgy, global prefix ONT-) — owns states, labels, cycles
App / solution one Linear Project under the shared team (pre-existing — never created per feature)
Feature (one per feature; Jira "epic") an Issue labelled type:feature, in the app project
Story (one per requirement) an Issue labelled type:story, parentId = the feature-issue
Task (one per atomic task) an Issue labelled type:task, parentId = the story-issue
Estimate numeric estimate (points, not hours)
Spec back-link links: [{url, title}] on the issue (shows as an attachment)
Initial state set state directly to Backlog — no transitions
Sprint a Cycle (assigned later by the sprint planner, not here)
Release grouping an optional project Milestone (milestone on the issue)

Nesting is reliable for the 3 levels above (feature→story→task), proven live. Because some Linear views flatten deep trees, the type:* labels are the primary way to read the hierarchy and nesting is secondary structure.

Inputs

  • documentation/specs/{feature}/tasks.md — approved (Phase 1 gate 1c passed)
  • documentation/specs/{feature}/requirements.md — for story grouping
  • documentation/specs/{feature}/design.md — for the feature-issue description
  • Docs URL for the spec page (Notion or Confluence) — for back-links
  • Linear team name or ID (e.g. Ontoledgy) — required to create issues
  • Linear project name or ID — the app's project (e.g. OL AI Context Library)
  • Default assignee (optional)
  • Optional: existing release milestone (from a release planner) — if present, task-issues are tagged with it

Project & feature handling: existing app project vs release milestone

Before creating anything, settle the placement:

  1. Confirm the app's Linear Project exists under the shared team. Use list_projects (filter by name). If it does not exist, ask the user to confirm the project name and create it once with save_project on the shared team (it is the app's home, not a per-feature container). Do not create a project per feature, and do not create a team per app — all apps share one team.

  2. Feature-issue strategy:

    • Release-skeleton feature-issue exists (created by a release planner): fetch it (get_issue), update its description with the full design overview + spec URL + repo spec-folder link, ensure it carries type:feature, and create stories/tasks beneath it. Do not create a second feature-issue.
    • No release plan, or feature not yet represented: create a new feature-issue labelled type:feature under the app project.
  3. Release milestone (optional): if the release planner created a project milestone for this release, pass milestone on the task-issues so the roadmap reflects them. Otherwise omit.

Outputs

Output Where
Feature-issue (one) ONT-NNN (global prefix), label type:feature, in the app project
Story-issues (several) ONT-NNN, type:story, parentId = feature-issue
Task-issues (many) ONT-NNN, type:task, parentId = story-issue
Ticket map documentation/specs/{feature}/ticket-map.md

Issue structure

Feature-issue (one per feature)

  • Title: {Feature Name} — {one-line description}
  • Description: overview + link to spec page (Notion/Confluence) + link to repo spec folder
  • Project: the app project · Team: the shared team (Ontoledgy / ONT-)
  • Labels: type:feature, feature:{feature-name}
  • State: Backlog

Story-issue (one per requirement group)

  • Title: the requirement user story ("As a {role}, I want {feature}, so that {benefit}")
  • Description: acceptance criteria from requirements.md (EARS format preserved)
  • parentId: the feature-issue · Project/Team: same as the feature-issue
  • Labels: type:story, feature:{feature-name}, req:{requirement-number}
  • State: Backlog

Task-issue (one per atomic task in tasks.md)

  • Title: task title from tasks.md
  • Description: task purpose · exact files to create/modify · _Leverage: references · _Requirements: back-link · spec section link · impl hints from design.md
  • parentId: the story-issue covering the referenced requirement
  • Labels: type:task, feature:{feature-name}, skill:{skill-name} (from the _Skill: annotation), agent:{engine} (codex or claude — see Execution-engine assignment), req:{requirement-number}
  • Estimate: points (see Estimate convention below)
  • Links: [{url: spec-section URL, title: "Spec — {section}"}]
  • Milestone: release milestone if one exists
  • Assignee: default assignee if configured
  • State: Backlog

Estimate convention

tasks.md carries _Estimate: in hours; Linear uses numeric points. Convert with the project's scale. Default heuristic when the team uses a Fibonacci scale: ≤2h→2, ≤4h→3, ≤1d→5, ≤2d→8, more→13. If the team's scale is configured as hours/linear, carry the hour value as the number. Record which convention was used in the issue map header so estimates stay comparable across features.

Execution-engine assignment

Each task-issue is labelled upfront with the engine that will implement it, so Phase 4's executor never decides at runtime. The engine is one of:

  • agent:claude — implemented by the routed Claude-native engineer skill (skill:{name}), with the full clean-code-reviewer loop.
  • agent:codex — implemented by delegated Codex via the Codex MCP.

Confirm the engine-routing label name against the live workspace first. This skill uses agent:* as the engine-routing convention (the pair that shipped and got adopted workspace-wide: agent:codex / agent:claude). Before assuming either name, run list_issue_labels (Step 3) and check which engine-routing pair already exists on the team. If the workspace already carries a different pair (e.g. a legacy exec:*), follow the live precedent rather than introducing a second, competing scheme — and flag the divergence to the user. Never create a new engine-routing pair when one already exists under a different name.

Default rule: classify each task simple/complex using task-executor's complexity-triage signals (estimate ≥ 5 pts / > 4h · more than 3 files · introduces/changes a public API, schema, or migration · domain is auth/payments/data-identity(BIE)/security · touches async/locking/transactions/ordering · requires new test files), then complex → agent:claude, simple → agent:codex. All derivable from tasks.md at backlog time. Set it as a default the user reviews — show it per task in the Step 4 preview and the issue map, and let the user override any task's engine before publishing. The agent:{engine} label is the single source of truth sprint-planner carries into the kickoff and sprint-executor reads. Like the other type:* / skill:* labels, the two agent:* labels must exist on the team before issues reference them (Step 3).

Workflow

Step 1 — Validate inputs

  • Confirm tasks.md exists and is marked approved; confirm the three spec files exist.
  • Confirm the shared Linear team and the app project are known (from documentation/workflow-config.md or user input). Resolve the project with list_projects.
  • Confirm the feature does not already have a feature-issue (search list_issues with label:type:feature + feature:{name} in the project). If one exists, ask: update existing or abort?

Step 2 — Parse tasks.md

Extract top-level groupings (→ candidate stories), individual tasks (- [ ] N.) with their _Requirements: / _Leverage: / _Skill: / _Estimate: fields, and group tasks by requirement to form stories.

Step 3 — Ensure labels exist

The hierarchy and routing live in labels, so they must exist before issues reference them.

  • list_issue_labels for the team first, and read the result before creating anything. Create any missing ones with create_issue_label (scope to the team via teamId):
    • the three hierarchy labels type:feature / type:story / type:task (one-time, on the shared team)
    • the engine-routing pair, but only after resolving which pair the workspace uses (see the guard below) — create agent:codex / agent:claude only if no engine-routing pair already exists; if a pair is already present under any name, reuse it and create nothing
    • feature:{feature-name} (once per feature)
    • req:{n} and skill:{name} as referenced by the tasks
  • Resolve the engine-routing pair before creating any engine label. From the list_issue_labels result, check whether the team already carries an engine-routing pair (the agent:* default, or a legacy pair under a different name such as exec:codex / exec:claude). If one exists, use that existing pair on all task-issues and tell the user the workspace diverges from the agent:* default when it does. Only create agent:codex / agent:claude when no engine-routing pair exists yet. Never create a second, competing pair.
  • Do not assume save_issue auto-creates labels — create them explicitly.

Step 4 — Preview before publishing

Produce the tree and the totals; ask the user to approve before any issue is created:

Project: {app project}   (Team {team})
Feature-issue: {feature} — {description}   [type:feature]
├── Story: As a {role}...  (sum: 13 pts)   [type:story, req:1]
│   ├── Task: Add columns to model       [type:task, skill:python-data-engineer, agent:codex,  5pt]
│   ├── Task: Write Alembic migration    [type:task, skill:python-data-engineer, agent:claude, 5pt]
│   └── Task: Add unit tests             [type:task, skill:clean-code-tests,     agent:codex,  3pt]
└── Story: As a {role}...  (sum: 8 pts)   [type:story, req:2]
    └── ...
Total: {N} issues, {P} points   ·   engines: {n} claude / {m} codex

Ask the user to approve before creating issues — and to override any task's agent: engine if they disagree with the default classification.

Step 5 — Create issues (capture IDs for nesting)

Use the Linear MCP in this order — each call returns an identifier (e.g. ONT-42) you pass as the next level's parentId:

  1. Feature-issue — save_issue (or save_issue with id to flesh out a release skeleton). Capture its identifier.
  2. Story-issues — one save_issue each with parentId = the feature-issue identifier. Capture each.
  3. Task-issues — one save_issue each with parentId = the parent story identifier, estimate, labels, links, and milestone if applicable.

Create in small batches and surface any API error immediately — do not continue on failure. The proven call shape (from the ONT-27 dogfood):

save_issue({
  title: "Add licence columns to LegalEntities model",
  team: "Ontoledgy",
  project: "OL AI Context Library",
  parentId: "ONT-41",                       // the story-issue
  labels: ["type:task", "feature:licence", "skill:python-data-engineer", "agent:codex", "req:1"],
  estimate: 5,
  state: "Backlog",
  links: [{ url: "<spec section URL>", title: "Spec — Data model" }],
  description: "<purpose · files · _Leverage · _Requirements · hints>"
})

If operating on a release-skeleton feature-issue, also update the release roadmap (milestone / release page) to reflect that this feature moved from "specced" to "in backlog".

Step 6 — Write issue map

Create documentation/specs/{feature}/ticket-map.md — the canonical mapping Phase 3/4 use. Commit it.

# Issue Map — {feature-name}    (estimate convention: points, Fibonacci)

Feature-issue: [ONT-40](https://linear.app/ontoledgy/issue/ONT-40)

| Task (from tasks.md) | Linear ID | Type | Skill | Engine | Estimate | Status |
|----------------------|-----------|------|-------|--------|----------|--------|
| 1. Add columns to model | [ONT-42](...) | task | python-data-engineer | codex | 5 | Backlog |
| 2. Write Alembic migration | [ONT-43](...) | task | python-data-engineer | claude | 5 | Backlog |
...

Step 7 — Update the docs surface & return

Append a "Linear Issues" section to the spec page (Notion or Confluence, via the docs adapter) with a table matching the issue map, so reviewers can trace spec → issues. Then return to caller with: feature-issue identifier + URL, count of stories and tasks, total points, ticket-map path, and the project board URL.

Mapping from backlog-manager (JIRA → Linear)

backlog-manager (JIRA) linear-backlog-manager
createJiraIssue epic save_issue labelled type:feature (Jira epics are features; no separate epic level)
createJiraIssue story parent:{epic} save_issue parentId:{feature} labelled type:story
createJiraIssue subtask parent:{story} save_issue parentId:{story} labelled type:task
addCommentToJiraIssue for back-link links:[{url,title}] on the issue (or save_comment)
estimate in hours estimate in points (convert; record convention)
project key (one per app) one shared team (global ONT- prefix) + one project per app
release-skeleton epic release-skeleton feature-issue, or project milestone
editJiraIssue to amend save_issue with id to amend

Updates and amendments

When a spec changes after issues are published:

  • New task added: save_issue a new task-issue under the right story; append to the issue map.
  • Task removed: set state to Canceled with a reason comment; strike it through in the issue map. Never delete issues — the audit trail matters.
  • Task scope changed: save_issue with id to edit description; update the issue map.
  • Estimate changed: save_issue with id to change estimate.

What this skill does NOT do

  • Does not author specs (Phase 1 / feature-spec-author)
  • Does not plan sprints or assign cycles (Phase 3 / sprint planner)
  • Does not execute tasks (Phase 4 / executor)
  • Does not log implementation details (Phase 5 / impl-logger)
  • Does not create the app's Linear Project per feature — the project is the app's pre-existing home

References

  • skills/backlog-manager/SKILL.md — the JIRA original; identical role and contract
  • Linear MCP: save_issue, save_project, list_projects, list_issues, get_issue, list_issue_labels, create_issue_label, list_issue_statuses, save_milestone, save_comment
  • Proven call sequence: feature-issue ONT-27 → stories ONT-28/29 → tasks ONT-30..34 in project "OL AI Context Library" (the trial that produced this skill; originally created as type:epic, since relabelled to type:feature per the decided standard)
  • Companion: impl-logger (Phase 5, tracker: linear), the tracker-adapter generalisation of the executors

Feedback

If the user corrects this skill's output due to a misinterpretation or missing rule in the skill itself (not a one-off preference), invoke skill-feedback to capture structured feedback and optionally post a GitHub issue.

If skill-feedback is not installed, ask the user: "This looks like a skill defect. Would you like to install the skill-feedback skill to report it?" If the user declines, continue without feedback capture.