gadak 0.21: 席を離れていた間に何があったか
月曜日。トラッカーを開く。リストはいつも通りに見える。課題が四十件、同じ列、同じ色。週末のあいだに何かが動いたことは分かっている。レビュアーがコメントを残し、ブロックしていた課題がひとつ閉じ、誰かが自分の課題二件の担当者を変えた。どれがそれなのか、リストは教えてくれない。教えてくれたはずの通知は金曜の夜に届き、自分は金曜の夜にそれを消した。金曜の夜の通知とは、そういうものだ。
トラッカーは知っていた。その出来事のひとつひとつが履歴にある。ただ、自分がしていた質問に合う文がなかっただけだ。質問は「プロジェクトの状態はどうか」ではなく「最後に見てから何が変わったか」だった。トラッカーは状態を保存する。戻ってきた人に必要なのは変化だ。
この文章はその隙間についてのものであり、その隙間の一部を埋めたリリースについてのものだ。0.18のエッセイは、データがどこにあるべきかを論じた。APIの向こうか、自分のマシンのファイルの中か。今回はいつについてだ。履歴をずっと積んできたミラーが、戻ってきたその瞬間に何を言えるか。
ミラーはもう知っている
gadakはトラッカーをローカルのSQLiteファイル1つにミラーする。そのトラッカーがJiraでもLinearでも、gadakに同梱の内蔵トラッカーでも同じだ。ミラーにはすべての課題の変更履歴とすべてのコメントがあり、その隣の二つ目のファイルには、自分がどの課題をいつ開いたかが残る。このうち新しいものは何もない。最初の同期のときからそこにあった。
0.21が加えたのは収集装置ではない。そのデータにようやく投げ始めた質問の集まりと、どの答えにもそれをどう計算したかの定義を並べて印字するという規則だ。このリリースのどの部分もネットワークに手を伸ばさず、新しくマシンの外に出るものもない。以下はすべて読み取りだ。
戻ってきて問う三つの質問
何が変わったか。 リストが薄い一行で開く。前回のセッション以降 3時間 · 7件の課題が変更 · うちこのアカウント担当 2件。境界は深夜零時でも「最後のログイン以降」でもない。自分の前回のセッションだ。読み取りと読み取りの間隔が三十分を超えないひとまとまり。課題を開くと詳細パネルが同じことをもっと小さな尺度でする。最終閲覧 3日前 — ステータス変更 2件、新着コメント 1件。この行はページが開いたときに一度固定され、作業中に数字が増えることはない。意図してそうした。増えていく数字は通知で、着いたときに一度読む行は気づきだ。欲しかったのは後者だった。
これはどれだけ滞っているか。 トラッカーは年齢を固定の数字で答える。72時間、そこから先は行が琥珀色になる。72時間は誰の数字でもない。誰かが設定ファイルに書き込んだ既定値だ。0.21はその基準をワークスペース自体から学ぶ。直近90日にチームが完了した課題のうち、一度も再オープンされていないもののサイクルタイムの85パーセンタイル。チームがたいていのことを二日で閉じるなら、四日目の進行中の課題はすでに異例で、マークはそう言う。三週間で閉じるチームなら、マークは三週間静かにしている。課題の期間を示すチップにマウスを載せるとチームのp85が見え、CLIのlist・ready・nextにはage_daysが付くので、エージェントも人と同じ数字を見る。
今週は速くなったか。 gadak retroは表をひとつ印字する。列はISO週。行はセッション数、着いてから最初の書き込みまでの時間、進行中の仕事の年齢(p85といちばん古いもの)、閉じた課題の数とかかった時間(中央値とp85)、そして不一致。不一致はすぐあとで扱う。表の下には毎回、すべての行の定義が印字される。--openはどのセルでもその裏にある課題をアプリに開くので、数字が行き止まりになることはない。表が週単位なのには理由が二つある。このうちのどれも一週間より短い区間では意味を持たないこと、そして振り返りが、チームがすでに記憶を頼りにこれらの質問をしている唯一の会議であることだ。
ミラーだけが作れる行
その表の最後の行が不一致だ。仕事は終わったと言うコメントが、ステータスはまだ終わっていないと言う課題に付いている場合。「マージしたので閉じます」「リリースブランチに反映済み」「対応済みです」。コメントは人が見た真実で、ステータスはトラッカーが記録した真実で、二つが食い違っている。
Jiraはこの行を作れない。コメント本文とステータスは別々のエンドポイントに住み、JQLにはジョインがない。ミラーは両方を一つのファイルに持っているので、質問はクエリ一つだ。開いたステータスの下に完了を示す調子のコメントをパネルが見つけると、静かなボタンを一つ出す。完了に移動。マウスを載せると、そのボタンを生んだ事実が見える。最新のコメントは完了を示しているが、ステータスはまだ In Review。一度閉じれば、その課題では二度と出ない。
このヒューリスティックの最初の版は、間違ったまま出荷した。部分文字列で照合していたので、「abandoned」の中に「done」があり、「unresolved」の中に「resolved」があり、「未完了」の中に「完了」があった。信号が逆を向いた。まさに、まだ終わっていないと言っているコメントを指したのだ。修正はパーサーではなくガードだ。英語の単語は単独で立っていなければならず、CJKの完了語の前後に否定の接頭・接尾が付いていてはならず、引用文とコードフェンスは剥がし、質問文は除外し、最後のステータス変更より新しいコメントだけを数える。十九行のテスト表が、古い規則でまず失敗してから新しい規則で通った。retroのその行は自分の定義の中にヒューリスティックと書いてあり、それは本気だ。
作らないと決めたもの
これらの信号のひとつひとつが、望まない機能から一歩の距離にあった。
スコアなし。retroは今週閉じた課題とサイクルタイムを示すが、人を順位づけしないし、人ごとの列もない。人への評価として読まれるフィードバックは、仕事へのフィードバックより行動を変える力が弱く、変えるときは悪い方向に変えやすい。古くて頑丈な研究結果であり、gadakが印字するすべての文の主語が読む人ではなく課題である理由だ。
通知なし。0.21のどれも割り込まない。セッション行、再開カード、年齢のマーク、完了に移動のボタンは、みな次に視線が向く場所で待っていて、言うことがなければ何も言わない。静かな朝には、セッション行はそもそも現れない。
固定SLAを規則にしない。滞留の基準は、標本が十分にあるかぎり常にワークスペース自体の分布だ。直近90日の完了が十一件になるまでは72時間に退き、設定画面はそのことをそのまま書いてある。固定の数字は定義ではなくフォールバックだ。
外に出るものなし。retroも、セッション行も、学習した基準も、すべてディスク上の二つのファイルから計算される。どんな集計もどこにも送られず、送る先のアカウントそのものがない。
エージェントの一行
もうひとつの変更がこの文章に属する。テキスト一行のものだが。コーディングエージェントがgadakを通してJira CloudやLinearに何かを書くと、コメントでもステータス遷移でも新しい課題でも、その末尾に— via gadak · 名前が付くようになった。
理由は退屈で、重要だ。それらのoriginではエージェントは人の資格情報で書き込み、トラッカーは二つを区別できない。0.21より前は、エージェントが残したコメントは自分が打ったものとまったく同じに見えた。間違うまでは構わない。間違ったあとは、誰の失敗なのか誰にも分からない。エージェントをトラッカーの中に入れるチームなら、まずその中でエージェントが見えなければならない。この一行はそれをする最小のもので、チームが別の決定をしているならactor.trailer = falseで外せる。
負けている場所
前回のエッセイの正直さの規則は、ここにも適用される。数字が見かけより弱い場所だ。
*この文章のすべての数字は、ワークスペースひとつから来ている。自分のものだ。*gadakのバックログはgadakの上で動いている。実際の週が積まれた実際のワークスペースだが、計器を作った本人が書いたデータ点ひとつでもある。0.21に置いた成功条件は機能の一覧ではなく、一つの文だった。自分ではない誰かが、自分のミラーの数字を持って、自分の言葉で、戻ってくるコストが下がったと言う文。その文はまだない。できたら、言い換えずにそのまま引用する。それまで、このリリースはミラーが何を計算できるかについての主張であって、それがあなたに何をしてくれるかについての主張ではない。
不一致の行はヒューリスティックだ。 単語境界と否定のガードで引き上げた精度は、一度閉じれば済むボタンには公正な取引だ。人についての報告書に載せる数字には足りない。行の下の定義がそう言っている。
Linearには変更履歴がない。 APIが課題の着手・完了時刻を返すのでフローの列はそこから埋まるが、その課題が次に動いたときにようやく埋まる。既存のLinearミラーはそれまでダッシュを見せる。
三十分は推測だ。 セッションの境界は既定値のあるパラメータで、五分から一日の間に縛られており、どの値がその行を作ったのか分かるように表の下に印字される。
二つの文章を足すと
0.18のエッセイの主張はひとつだった。データをファイルに入れれば、APIが問えなかった質問がクエリ一つになる。この文章は二つ目の主張をする。履歴がそのファイルにあれば、戻ってきた瞬間の質問にもそこから答えられる。何が変わったか、これはどれだけ滞っているか、今週はうまくいったか。新しく集めるものなしに、横に定義のない数字なしに。
どちらの主張も、真であるためにエージェントを必要としない。どちらもエージェントが部屋にいると鋭くなる。同じミラーを読むエージェントは、同じセッション行、同じ年齢、同じp85を見て、同じ数字で答えるからだ。
試す
gadak retro # 週の表、その下に定義
gadak retro --open closed --week 1
gadak list # 未解決の課題、優先度の横にage_days
ライブデモは同じUIを534件のフィクスチャの上でブラウザに開く。セッション行もそこにある。それぞれの信号がどの研究に依っていて、それで何をしないと決めたかはTHEORY.mdにある。行の定義はDERIVE.mdに、自分のミラーでそのまま実行できるSQLとして書かれている。