月曜の朝七時。コーヒーがまだ熱くて、Slackの未読が冷めている時間帯。この記事は、そういう時間に読めるよう置いておく。通勤電車のなかで、隣の人の肩越しに盗み見されても恥ずかしくない程度の、現場の話だ。
最初に白状しておく。私はコードを書けないスクラムマスターだった。「だった」と過去形にできたのは、ここ数週間の出来事のおかげで、その肩書きが少しだけ嘘になったからにすぎない。
速いチームほど、何も残らない
ここ一年、チームは速くなった。AIに下書きを投げ、テスト設計のたたき台を吐かせ、レビューの観点まで先回りさせる。ベロシティのグラフは右肩上がり。経営に見せると、みんな満足そうにうなずく。
ところが、だ。スプリントレビューのたびに、私の胃の底に小石が一つずつ溜まっていった。速くなったのに、組織サーベイの成長指標は、良くなるどころか芳しくない方向へまっしぐら。タスクは溶けるように消えていくのに、消えたあとに手触りが残らない。畑は耕されているのに、収穫の話を誰もしない。
速さは、効きの早い鎮痛剤。痛みは黙るが、患部はそのまま残っている。効いている間は、誰も病院に行こうとしない。研究開発という畑に、気づけばそれなりの年輪を重ねていた身。速さの正体が「学びの副産物」でしかないことくらい、何度か痛い目を見れば、嫌でも体で覚える。速さそのものを目的に据えた瞬間、チームは"消費"を始める。自分の在庫の知識を切り崩し、それを「こなした」と呼ぶ。新しい引き出しは、一つも増えていない。
あるスプリントのふりかえりで、一人のメンバーがぽつりと言った。「自分の知識の中でタスクを消化してしまって、あまり成長を実感できなかった」と。声には、本気で困っている色がにじんでいた。その声を聞いて、私は決めた。成長を、目に見える場所に引きずり出す。畑のなかで何が芽吹いたのかを、本人にも、隣の席にも、経営にも、嫌でも見えるようにする。
なぜ「草」だったのか
可視化、と口で言うのは簡単。難しいのは、それが"裁きの道具"に化けないようにすることだ。スキルの一覧を作って点数をつければ、それは静かに人事評価の影武者になる。誰かが誰かと比べられ、低い数字をつけられた人間は、二度と本音を書かなくなる。心理的安全性という言葉は、こうして死ぬ。
私が欲しかったのは、通知簿ではなかった。GitHubの、あの草だ。コミットを重ねると緑が濃くなる、あの罪のないマス目。あれは順位をつけない。隣の誰かと比べさせない。ただ「今日、手を動かしたね」と肯定するだけの、無口な相棒。あの思想を、スプリントの学びに移植したかった。
縦にスキルのカテゴリ、横にスプリント。そのスプリントで「塗りが動いた」と手を挙げた人数だけ、マスが緑に染まる。多ければ濃い緑。ゼロなら灰色のまま、けれど責めない。森が育つのを、全員で同じ画面から眺める。それだけ。
問題は、それを作る人間が、私だったことにある。
コードを書けない男が、コードを書いた
正直に言う。私のJavaScriptは、十年前にコピペで止まっている。var と let の宗派対立に、いまだに肩身が狭い。だが今は、隣に壁打ち相手がいる。Claude Coworkに向かって、私はこう投げた。「カテゴリごとにGitHubの草を生やすみたいに、各スプリントの成長を可視化したい」。
返ってきたのは、説教ではなく、たたき台だった。これがAIと組む醍醐味で、こちらの語彙が幼くても、向こうは"意図"を拾ってくる。仕様書を書けない発注者の、頭の中の落書きを、動くHTMLに翻訳してくれる。他人の書いた原稿用紙のマス目を、こちらの言葉で埋め直してくれる相棒、とでも言えばいいか。
草の濃さを決めるロジックは、拍子抜けするほど短い。
// そのスプリントで「伸びた」と手を挙げた人数を数える
function grewCount(sprint, cat) {
return sprint.members.filter(m => (m.grew || []).includes(cat)).length;
}
// 人数を 0〜4 の濃さに丸める(GitHubの草と同じ5段階)
function level(n) {
return n <= 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n === 3 ? 3 : 4;
}
たったこれだけで、灰色の地面に緑が点り始める。データさえあれば、可視化の本体は驚くほど痩せている。肥えているのは、データを集める仕組みと、人の言葉を機械が読み解くところ。後者で、私は一度、派手に転ぶことになる。それは後の章で。
データの入り口は、ふりかえりの最後に九十秒で答えるGoogleフォームにした。設問は欲張らない。「成長を感じたか」「学ぶ時間を取れたか」「このペースは持続できるか」を五段階で。それから、伸びたカテゴリにチェック。最後に、自由記述で「次に伸ばしたい一つ」を書いてもらう。この"自由記述"が、後で私の足を派手にすくう。気づいた読者は、勘がいい。
全員の画面に、同じ草を
初心者が必ず踏む地雷の在り処は、幸い、踏む前に見えていた。
完成したHTMLファイルを得意げにチームへ配って終わり、にはしなかった。HTMLを配るだけでは、入力したデータが各自のブラウザ(localStorage)のなかにしか残らない。五人に配れば、中身の違う五つの畑が別々にできあがる。隣の人が何を育てたかは、誰の画面にも映らない。そうなる前に、設計を一段ずらしておく。データは、一か所に集めてからでないと意味を持たない。
そこで Google Apps Script の出番。フォームの回答を読み、草マップが食べられる形のJSONに変換し、画面そのものもAppsScriptから配信する。一つのURLを開けば、全員が同じ最新の畑を見る。サーバー側でデータを画面に流し込むので、誰のブラウザでも結果は同じ。
function doGet(e) {
// 画面(HTML)を返す。データはサーバ側で埋め込む
const tmpl = HtmlService.createTemplateFromFile('grass');
tmpl.dataJson = JSON.stringify(buildGrassJson_()).replace(/</g, '\\u003c');
return tmpl.evaluate()
.setTitle('成長の草マップ')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
URL一つで、全員が同じ畑の前に立つ。配り直しも、面倒なインストールもいらない。ここまでは、わりと順調だった。本当の落とし穴は、もっと静かなところに口を開けていた。
機械が、人を読み違えた夜
前に蒔いた種が、ここで芽を出す。それも、雑草の顔で。
「次に伸ばしたい一つ」を自由記述にした以上、書かれた日本語を機械がカテゴリに振り分けねばならない。私は素朴なキーワード照合を書いた。「テスト」と書いてあれば品質カテゴリ、「設計」と書いてあれば設計カテゴリ。一見、無害。
ところが、あるメンバーがこう書いていた。
テスト実行中の不明点を解決できるよう「A. ドメイン/業務知識」を高めたい
本人は、はっきり「A. ドメイン/業務知識」と名指ししている。なのに私のコードは、文頭の「テスト」に飛びついて、これを品質カテゴリと判定した。来期の焦点を集計したら、品質に四票。本人の意思は、機械の早とちりに踏み潰されて、どこにも残らなかった。
これを「ただのバグ」で片づけるわけにはいかなかった。本人がはっきり口にした願いを、システムが横から書き換える。やっていることは、検閲とそう変わらない。一度でもこれが起きれば、メンバーは静かに学習する。どうせ機械が適当に振り分けるなら、丁寧に書くだけ無駄だ、と。次のスプリントから、自由記述の欄はやせ細っていく。声を集めるはずの仕組みが、声を間引く装置へ。育てたかったのは草で、刈ろうとしていたのは、人の本音だった。ぞっとした。
修正の方針は、人間の明示を最優先にすること。文中に「A.」のようにカテゴリが名指しされていたら、キーワードの当て推量より、そちらを必ず立てる。
function guessCat_(text) {
const t = String(text || '').trim();
if (!t) return '';
// ① 文中の明示コード「A.」「F.」を最優先(API. の誤検出は区切り限定で回避)
const m = t.match(/(?:^|[\s「『((、,,])([A-J])\s*[\..]/);
if (m) return m[1].toUpperCase();
// ② 次に正式名の一致、最後にキーワード推定(ここは省略)
// ...
}
直したあと、件のメンバーの票は、本来あるべき「A」の畑に戻った。たった一票。されど一票。その一票が、「お前の言葉はちゃんと届いている」という、システムからの返事になる。測定の精度の話に見えて、これは信頼の話だ。
ついでに、どうしても変な読み違いが残ったとき用に、設定ファイルへ一行足すだけで矯正できる逃げ道も用意した。機械の推測を、人間がいつでも上書きできる。AIに任せた領域に、人間が手綱を残しておく。この感覚は、現場でAIと付き合ううえで、たぶん一番大事な握り方。
Sprint 1 の畑に、何が芽吹いたか
最初のスプリントを終えて、五人ぶんの草が地面に点った。
濃く染まったのは、品質とテストの列。三人が「ここが伸びた」と手を挙げた。新しいテストの作法を覚えた人。どこまで検証すべきかの線引きを、誰かの指示を待たず自分で引けるようになった人。AIを壁打ち相手にして、設計の筋道を立てた人。やり方は、それぞれ違う。共通していたのは、速さの裏で、引き出しがちゃんと一つ増えていたこと。安心した。
成長実感の平均は五点満点で二・六。学ぶ時間は三・〇。持続可能性は三・四。胸を張れる数字ではない。むしろ、初回としては正直な数字。全員が満点をつけるサーベイは、サーベイではなく、忖度の貯金箱だから。低めの数字が出たことに、私はむしろ安堵した。本音が書ける土壌は、まだ枯れていない。
そして、来期に伸ばしたい一つとして、品質に票が集まった。冒頭で「自分の知識だけでタスクを消化してしまった」と漏らした、あの声の主。次の畑を品質と定めた。在庫を切り崩していた手が、新しい種に伸びようとしている。可視化が効いたかどうか、まだ分からない。けれど、本人が自分で次の一歩を名指しできたこと。それ自体が、灰色だったマスに芽が出た証拠だと、私は受け取った。
測るのは、裁くためではない
ここまで読んで、「結局はエンゲージメントサーベイの焼き直しでは」と斜に構えた読者もいるはず。その疑いは正しい。世の多くの可視化は、数字を握って人を並べ替えるために使われ、現場の口を重くしてきた。私はそれを、何度も見てきた。
この草マップが、ただのダッシュボードと違うと言い張れる根拠は、たった一つ。順位をつけないこと。誰が何点か、ではなく、畑全体でどこに緑が増えたか、を見る。個人を裁くための虫眼鏡ではなく、森を一緒に眺めるための窓。だから、ふりかえりでこの画面を映しても、誰も身構えない。犯人を探さず、芽の出ていない列を見て「次はここに水をやろうか」と相談する。数字が、対話のきっかけに化ける。
人を「コスト」として見るなら、可視化は監視になる。人を「資本」として見るなら、可視化は投資の進捗報告になる。同じ緑のマス目が、見る側の腹づもり一つで、鞭にも、肥料にもなる。私はこの道具を、肥料の側に置くと決めている。
速さの時代に、あえて学びの余白を守る。急がば、学べ。古臭い格言を、AIという最新の道具で裏打ちする。この矛盾めいた組み合わせが、たぶん、これからのスクラムマスターの仕事になる。AIに任せて空いた手で、何をするのか。私は、その空いた手で、畑に水をやることにした。
おわりに——コードを書けない、と言い訳していた過去の自分へ
最後に、この記事をいちばん読ませたい相手は、数週間前の私自身だ。「コードが書けないから、見える化なんて無理だ」と決めつけて、胃に小石を溜めていた、あの私。
伝えたいのは一つ。発注者の語彙が幼くても、意図さえ尖っていれば、AIは動くものに翻訳してくれる。必要なのは流暢なJavaScriptではなく、「何のために、誰の何を守りたいのか」という、一行の意地だった。道具は、もう手の中にある。あとは、畑に出るかどうか。
月曜の朝、コーヒーが冷めきる前に。あなたのチームの灰色のマス目に、最初の一粒を蒔いてみては。緑が点る瞬間は、想像よりずっと、こちらの胸を温める。