
26時間で4リリース: 言語設定の配管と「ブリッジリリース」
GeekBye v1.7.6からv1.8.1まで: ラップトップから一度も出たことのなかった言語設定、本当のキーバインドを表示するCmd+/オーバーレイ、コード変更ゼロのバージョン — そして自動アップデートフィード移行の鶏と卵問題。
2026年2月のある木曜の朝から金曜の午後にかけて、GeekByeは四つのリリースを出荷しました: v1.7.6、v1.7.7、v1.8.0、そしてv1.8.1 — 合計16コミット、最初のタグから最後のタグまでおよそ26時間。どれひとつとして見出しになるものではありません。しかし合わせて見れば、小さなリリースが続く週が実際に何を含んでいるかの肖像になっています: ようやく旅を終えた機能、生活の質を上げるオーバーレイ、コードをひとつも含まないバージョン番号、そして心底教訓的なリリースエンジニアリングの一幕です。
ラップトップから出なかった言語
GeekByeには2025年9月からトランスクリプトの言語設定がありました。それは動いていました — ローカルでは。スペイン語を選べば、オンデバイスの音声認識パイプラインは律儀にスペイン語を文字起こしします。しかしv1.7.5のコードベースをその設定でgrepすると、見つかるのはちょうど三箇所: オーディオハンドラ、Settings UI、そして設定フックです。APIクライアントにはない。セッショントラッカーにもない。4か月ものあいだ、マシンを離れるすべてのリクエストは言語を知らないままでした: バックエンドのセッション記録は自分が何語を表しているのか知らず、AIチャットは「これはスペイン語だ」というヒントを一切持たないスペイン語のトランスクリプトを受け取っていたのです。
v1.7.6は、この設定が旅を終えたリリースです — 2コミット、1日。オーディオセッションの開始はペイロードにtranscriptLanguageを載せるようになり、AIのストリームチャットリクエストにも同じフィールドが加わりました。設定を読み、autoや未設定のときは意図的にundefinedを返す小さなヘルパーを通して配線されているので、古いバックエンドは知らないフィールドに詰まる代わりに、優雅に劣化します。差分には静かなおまけの修正も隠れています: 言語を渡すために、セッション開始は言語解決の_あと_へ移動する必要がありました — 私たちの読みでは、これは同時に、セッションが開始され(制限にカウントされ)、その直後に言語解決が失敗して孤児になる、というエラー経路も閉じています。
教訓は一般化できます: 設定は、UIと効果を持った時点で出荷済みなのではありません。それを知るべきすべての消費者に届いた時点で出荷済みなのです。私たちの設定はネットワーク境界で4か月止まっていて、誰も気づきませんでした。ローカルの挙動 — 目に見える挙動 — がずっと正しかったからです。(記録のために言えば、これは言語処理の粗い最初の一手でした; AIに会話の言語で実際に_答え_させることを教えるのは、この物語のずっと後の章です。)
Cmd+/ — キーバインドについて嘘をつかないオーバーレイ
v1.8.0のユーザー向け機能は、Cmd+/で開くキーボードショートカットのオーバーレイです — 193行の新規コンポーネントと、盗む価値のあるひとつの設計判断: ハードコードされたチートシートをレンダリングしないこと。ライブのショートカット設定を取得してcustomKeys || defaultKeysをレンダリングするので、キーをリマップしたユーザーには_その人の_キーが見えます。変更した人にデフォルトを見せるショートカットオーバーレイはドキュメントではありません; きれいなタイポグラフィをまとった誤情報です。
残りは小さな正しさの積み重ねです: オーバーレイは画面のどちら側に余裕があるかに応じてアプリカードの左か右に自分を配置し、Escapeで、もう一度のCmd+/で、あるいは外側のクリックで閉じます。Cmd+/自体も、他のすべてのショートカットと同じリマップ可能なプリセットシステムに加わります — これは重要です。Cmd+/はほとんどのエディタで「コメントの切り替え」であり、開発者向けのツールが、動かすこともできない形でエディタのキーを占拠すべきではないからです。
ブリッジリリース
面白いエンジニアリングは、誰も二度見しないバージョン番号の中で起きていました。v1.8.0はプロジェクトのリリースを新しいGitHubオーガニゼーションへも移行しました — 表面上はorgの整理整頓ですが、デスクトップの自動アップデートにはひとつの性質があります: フィードURLはバイナリに焼き込まれているのです。すべてのv1.8.0インストールは新しいオーガニゼーションのリリースをポーリングします。そして世に出ているすべてのインストール — 全部がv1.7.7以前 — は、そこに何かが現れない限り、永遠に古い方をポーリングし続けます。
それが鶏と卵です: 次のリリースを新しいリポジトリだけに公開すれば、既存のフリート全体はそれを永遠に見ません。v1.8.0のタグの16分後、リリーススクリプトに新しいフラグが着地しました: --publish-owner。electron-builderがアーティファクトをアップロードする先を、ビルドのあとに書き換えるものです — コードコメントの言葉を借りれば、明示的に「コンパイル済みのアプリコードに影響を与えずに」。トリックはそれだけで、そしてそれこそが正しい継ぎ目です: バイナリに焼き込まれたフィードと、アーティファクトのアップロード先は別々の判断であり、移行にはその二つを一度のリリースだけ切り離すことが必要なのです。v1.8.1を新しいフィードを指すようにビルドし、古いリポジトリにアップロードする; 古いクライアントはそこでアップデートを見つけてインストールし、目を覚ますと新しいオーガニゼーションをポーリングしています。コミットメッセージはこれを「ブリッジリリース(bridge release)」と呼んでいて、それは正しい名前です。v1.8.1はv1.8.0の2時間20分後にタグ付けされました。(このプロジェクトが自動アップデートを恐怖に近い敬意をもって扱う理由の起源については、アプリを殺せなくした自動アップデートを。)
そしてv1.7.7は? 1コミット。バージョンバンプそのものです。修正もリバートも、履歴の中の説明もありません — 私たちの最良の読みは、再実行が必要になったpublishです。物語をでっち上げるより、そう認めるほうがいい。バージョン番号は時に、ソフトウェアのリリースが現実世界のつまずきを伴う現実世界のプロセスであって、ソースツリーの純粋関数ではないからこそ存在するのです。そもそもなぜ1.7が1.8になったのか: それを語るコミットはありませんが、フィード移行こそが意味のある互換性境界です — すべての1.8.xバイナリは、すべての1.7.xバイナリとは別のオーガニゼーションを見ています — そしてそれは、どんな機能よりもマイナーバンプに値します。
この週が教えてくれた三つのこと
- 設定はすべての消費者まで追跡せよ。 言語設定は4か月間「完成」していながら、バックエンドは何も知らないままでした。目に見えるローカルの挙動が正しかったことこそが、このギャップを生き延びさせたのです — 監査の問いは「この値を他に誰が知るべきか?」であり、あらゆる境界で問うべきものです。
- ドキュメントではなく、ライブの設定をレンダリングせよ。 ショートカットオーバーレイは、ショートカットシステムが使うのと同じ信頼できる情報源を読みます。それ以外のやり方は、ユーザーが最初にカスタマイズした瞬間からずれていきます。
- フィード移行には、両方の世界に生きるリリースがひとつ必要だ。 バイナリには新しいフィード、アップロードは古いリポジトリへ。リリースツールがこの二つのターゲットを分離できないなら、必要になる前にフラグを足しておくこと — 私たちのフラグは必要になった16分後に届きました。ぎりぎりセーフと数えていいでしょう。
v1の物語の前の章は、ログインページこそがデモである(v1.7.5)を; そして弧の全体については、ソフトウェアを完璧に出荷することの解剖学をご覧ください。