Linear極限活用術:CyclesとRoadmapsで構築する、摩擦係数ゼロのアジャイル・パイプライン
筆者は長年、数々の開発現場で「ツールに殺されるエンジニア」を見てきた。Jiraの重厚長大な設定画面にエンジニアの魂がすり減り、Confluenceの迷宮でドキュメントが死んでいく。アジャイルを標榜しながら、実態は官僚的なチケット更新作業に追われる姿は悲劇でしかない。
そこで我々がたどり着いた結論が Linear だ。
キーボードショートカット駆動、ミリ秒単位で描画されるネイティブライクなUI、そして何より「開発者の認知的負荷(Cognitive Load)を最小化する」という強烈な設計思想。
本稿では、Linearの Cycles(スプリント運用の核心) と Roadmaps(長期ビジョンの抽象化) を骨の髄までしゃぶり尽くし、ベロシティの限界を突破するための実践的アーキテクチャを解説する。表面的などこにでもあるマニュアルではない。APIやCLI、自動化スクリプトを駆使し、組織の血流となる開発パイプラインを構築する「極限の知見」を授けよう。
—
1. 内部アーキテクチャの理解:なぜLinearは速いのか
ツール選定において、その背景にあるデータモデルを理解することは不可欠だ。Linearは、従来の階層型(プロジェクト>エピック>タスク>サブタスク)の呪縛を断ち切り、「イシュー(Issue)中心のフラットかつグラフ構造」を採用している。
- GraphQL API First: すべてのクライアント操作は厳密に型付けされたGraphQLのエンドポイントを叩いている。これは我々エンジニアにとって最高の福音だ。UIでできることは、100% APIで自動化できる。
- 楽観的UI更新(Optimistic UI): ネットワークの往復を待たずにUIが即座に反応する。この「摩擦のなさ」が、エンジニアにチケット更新を億劫にさせない最大の要因である。
このアーキテクチャを理解した上で、CyclesとRoadmapsをどうハックすべきかを見ていこう。
—
2. Cycles駆動開発:摩擦なきスプリント運用の極意
スクラムのアンチパターンの一つに、「スプリントプランニングや振り返りのための事務作業がエンジニアの時間を奪う」というものがある。LinearのCyclesは、この無駄を極限まで削ぎ落とす。
2-1. 自動ローリング・サイクル(Auto-rolling Cycles)の設計
多くのチームが陥る罠は、手動で次のサイクルを作成し、溢れたチケットを手動で移行する作業だ。これを完全に自動化する。
Linearの設定で `Auto-close completed issues` と `Roll over incomplete issues` を有効化するのは基本中の基本だ。さらに踏み込み、チームのベロシティのブレを吸収する「2週間固定サイクル+バッファ設計」を取り入れよ。
- サイクル期間: 隔週月曜日 00:00 UTC 発動
- キャパシティ管理: 過去3サイクルの完了ストーリーポイントの移動平均(Moving Average)に対し、80%の負荷に設定する。100%で計画するチームは、不確実性を排除しきれていない未熟なチームだ。
2-2. 完了定義(DoD)の強制とステータス遷移の美学
Linearのカスタムワークフローを使い、ステータスの遷移に厳格なガードレールを設ける。
[Backlog] -> [Todo] -> [In Progress] -> [In Review] -> [QA / Staging] -> [Done]
│
└─(CI/CD Hook)─┘
ここで重要なのは、`In Review` から `Done` への遷移を人間の手で行わせないことだ。GitHub / GitLabのWebHookとLinear APIを連携させ、PRがマージされた瞬間に自動でステータスを更新する。これの実現方法については後述する。
—
3. Roadmaps:抽象と具象を繋ぐフラクタル構造
Roadmapsは、経営陣が見たい「マイルストーン」と、開発陣が見たい「イシュー」のギャップを埋めるための機能だ。ここでの最大のアンチパターンは、「ロードマップ用にとりあえず作った巨大なタスク群が、現場のコードと乖離していくこと」である。
3-1. プロジェクト(Projects)とロードマップの直交設計
LinearのRoadmapsは、複数の「プロジェクト」をタイムライン上にマッピングする。
ここで、プロジェクトは「期限付きの成果物(Outcome)」であり、単なる機能(Feature)のリストであってはならない。
- 悪い例: 「ユーザー管理機能の実装」(いつ終わるか曖昧、成果が不明確)
- 良い例: 「Q3認証基盤リプレイスによるSLA 99.99%達成」(成果が定量的)
このプロジェクトをRoadmapsに配置し、その傘下にCyclesをまたぐイシューを紐付ける。これにより、経営陣はマクロな進捗を俯瞰でき、エンジニアは目の前のサイクルタスクがどのビジネス価値に直結しているかを常時意識できる。
—
4. エキスパート向けハック:APIとCLIによる完全自動化
ここからが本稿の真骨頂だ。UIをポチポチ叩く作業は人間ではなく機械にやらせる。LinearのGraphQL APIとCLIを用いた、現場で即座に使える自動化スクリプトを公開する。
4-1. 毎週のサイクル開始・レポート生成を自動化するNode.jsスクリプト
以下のスクリプトは、LinearのGraphQL APIを叩き、前サイクルの未完了チケットを分析し、Slackへサマリーを飛ばすとともに次サイクルへのアサインメントを最適化する基幹スクリプトの断片である。
// linear-cycle-optimizer.js
// 必要な環境変数: LINEAR_API_KEY, TEAM_ID
const https = require(‘https’);
const LINEAR_API = ‘https://api.linear.app/graphql’;
const API_KEY = process.env.LINEAR_API_KEY;
async function queryLinear(query, variables = {}) {
const data = JSON.stringify({ query, variables });
const options = {
hostname: ‘api.linear.app’,
path: ‘/graphql’,
method: ‘POST’,
headers: {
‘Content-Type’: ‘application/json’,
‘Authorization’: API_KEY
}
};
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let body = ”;
res.on(‘data’, (chunk) => body += chunk);
res.on(‘end’, () => resolve(JSON.parse(body)));
});
req.on(‘error’, reject);
req.write(data);
req.end();
});
}
// アクティブなサイクルの未完了チケットを取得してロールオーバーを検知する例
async function analyzeActiveCycle(teamId) {
const query = `
query TeamActiveCycle($teamId: String!) {
team(id: $teamId) {
activeCycle {
id
name
issues {
nodes {
id
title
state {
name
}
assignee {
name
}
}
}
}
}
}
`;
const result = await queryLinear(query, { teamId });
const cycle = result.data.team.activeCycle;
console.log(`Analyzing Cycle: ${cycle.name}`);
const incompleteIssues = cycle.issues.nodes.filter(
issue => issue.state.name !== ‘Done’ && issue.state.name !==ئی ‘Canceled’
);
console.log(`Incomplete issues count: ${incompleteIssues.length}`);
// ここにSlack通知や自動再割り当てのロジックを注入する
}
// 実行エントリーポイント
if (require.main === module) {
analyzeActiveCycle(process.env.TEAM_ID).catch(console.error);
}
4-2. GitHub ActionsとLinearの密結合:PRマージによるステータス自動同期
CI/CDパイプラインからLinearを直接操作し、開発者の手を一切煩わせずにステータスを同期する。
ブランチ名にLinearのイシューID(例: `ENG-123`)を含める命名規則を強制せよ。
以下のGitHub Actionsワークフローは、PRがマージされた際に、対応するLinearのイシューを自動的に `Done` に移行するスニペットである。
name: Sync Linear Issue Status
on:
pull_request:
types: [closed]
jobs:
update-linear:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Extract Issue ID from Branch
id: extract
run: |
BRANCH_NAME=”${{ github.event.pull_request.head.ref }}”
# 例:feature/ENG-123-fix-auth のような形式から ENG-123 を抽出
ISSUE_ID=$(echo $BRANCH_NAME | grep -oE ‘[A-Z]+-[0-9]+’ || true)
echo “issue_id=$ISSUE_ID” >> $GITHUB_OUTPUT
- name: Update Linear Issue to Done
if: steps.extract.outputs.issue_id != ”
uses: actions/github-script@v6
with:
script: |
const issueId = ‘${{ steps.extract.outputs.issue_id }}’;
const apiKey = ‘${{ secrets.LINEAR_API_KEY }}’;
// Linear GraphQL mutation via fetch
const query = `
mutation UpdateIssueStatus($issueId: String!, $stateId: String!) {
issueUpdate(
id: $issueId,
input: { stateId: $stateId }
) {
success
issue {
identifier
state { name }
}
}
}
`;
// ※ 実際の実装ではあらかじめDoneステータスに対応するUUIDを取得しておく必要がある
console.log(`Syncing issue ${issueId} to Done…`);
(※注: 現場の本番環境では、ステータスIDのキャッシュ機構やエラーハンドリング、リトライロジックを強固に実装すること)
—
5. 組織のサイロ化を防ぐナレッジ共有の極意
「タスク管理ツール」としてのLinearの枠を超え、チーム全体のコンテキスト共有ハブとして機能させるための極定石を授ける。
1. Document機能の活用: Linear内にあるDocs機能は、Confluenceのような「誰も見ないゴミ溜め」になりにくい。なぜなら、イシューやプロジェクトと直接インラインでリンクできるからだ。 アーキテクチャ決定レコード(ADR)や仕様書は、独立したWikiに書くな。プロジェクトの親画面、あるいは関連するイシューに紐付けろ。
2. Updates機能による非同期文化の醸成: 週に一度の長ったらしい定例ミーティングを廃止せよ。代わりにLinearの「Project Updates」機能を用い、各テックリードに「進捗(Progress)、課題(Issues)、次週の計画(Next Steps)」を毎週金曜日に文字ベースで投稿させる。Signal(シグナル:On Track, At Risk, Off Track)のアイコンを視覚的に連動させることで、経営陣もマネージャーも、会議室に籠ることなく一目でプロジェクトの健康状態を把握できる。
—
結び:ツールに魂を売り渡すな、ツールを骨の髄まで従えよ
Linearは単なるチケットトラッカーではない。それは、エンジニアリング組織の「思考のスピード」をそのままコードに変換するためのアクセラレータである。
Cyclesでスプリントの摩擦係数を削ぎ落とし、Roadmapsでビジョンとコードを直結させ、APIと自動化スクリプトで定型作業を駆逐する。このパイプラインが完成した時、あなたのチームのベロシティは次元の違う領域へと到達するだろう。
さあ、エディターを閉じ、Terminalを開け。今すぐ次のサイクルを最適化しろ。