日々の心労に加えてプライベートで暴行やストーカーの被害に遭ってメンタルを壊し、3か月ほど外界との接続をほぼ絶って療養しておりました。
治療により日常生活もままならない状態からはひとまず回復しました。7月からの復職を目指すと主治医と相談し、復職の意思を表明していたところだったのですが、この度残念ながら退職となりました。
この先どうするかは未定です。面白い話があったらお声がけください。
またどこかで。
──やくしまるえつこ「ロンリープラネット」
日々の心労に加えてプライベートで暴行やストーカーの被害に遭ってメンタルを壊し、3か月ほど外界との接続をほぼ絶って療養しておりました。
治療により日常生活もままならない状態からはひとまず回復しました。7月からの復職を目指すと主治医と相談し、復職の意思を表明していたところだったのですが、この度残念ながら退職となりました。
この先どうするかは未定です。面白い話があったらお声がけください。
またどこかで。
──やくしまるえつこ「ロンリープラネット」
iwillblog -> I've blogged!
2026-03-20(金)〜2026-03-22(日)の3日間で開催されたPHPerKaigi 2026に登壇者として参加しました。
自分で写真をほぼ撮らなかったので、登壇時に撮影いただいたものを……

Day 0に「PHP 7.4でもOpenTelemetryゼロコード計装がしたい!」というタイトルで40分トークをしました。
OpenTelemetryのゼロコード計装がPHPに対して用意されており、PHPのアプリケーションではコードを編集することなくトレースを出力させることができます。これはPHP 8でZend Engineに追加されたObserver APIによって実現されています。OpenTelemetry拡張モジュールは、任意の関数を指定して前後にフック処理を登録する関数を提供します。自動計装ライブラリは、拡張が提供するフック登録関数を利用して、フレームワークやライブラリごとの主な関数に対してテレメトリーを計装する処理を加えていきます。PHPのオートロードの仕組みで登録処理が自動で行われるため、結果として、OpenTelemetry拡張モジュールのインストール+composerによる自動計装ライブラリinstallだけでゼロコード計装が実現されるというわけです。
PHP 7.4以前ではObserver APIが使用できないため、これらのバージョンではOpenTelemetry公式のゼロコード計装の仕組みは使用できません。しかし、理屈としては関数にフックを仕掛ける仕組みさえあればゼロコード計装できるはずです。そこで、PHP 7.4でも使える zend_execute_ex 関数ポインタを置き換え、元の処理をwrapし前後に任意の処理を追加できるようにする拡張モジュールを自作しました。また、この拡張モジュールに合わせた自動計装ライブラリもまた自作しました。発表中では、実際にPHP 7.4+Laravel 8のアプリケーションに対して自作したゼロコード計装の仕組みを導入するデモを行い、Jaegerでトレースが閲覧できることを確認しました。
作成したPHP拡張モジュール・ライブラリのソースコードは以下のリポジトリで公開しています。今後、他の人も簡単にPHP 7.4向けのOpenTelemetryゼロコード計装を導入できるように、拡張のパッケージ提供やライブラリのPackagist登録などを進めていく予定です。
膝を怪我していたり頭を怪我していたりスマホを壊したりと散々なコンディションで、現地には多くの時間滞在できなかったのですが、短い間ながらも初めてのPHPerKaigiを楽しませてもらいました。特にLTが演出も発表内容も非常によかったですね。
私のセッションがPHP 7ネタだったのですが、あるスポンサーブースの企画で、PHP 7系のユーザーが現在もそれなりにいることを改めて把握しました。アップデートできることを祈りつつ、なかなか上げられないレガシーアプリケーションにもオブザーバビリティを提供できるように今後もやっていくぞ!という気持ちになりました。
\PHPerKaigiのブース運営終了👍/
— DELTA Tech (@delta_sevenrich) 2026年3月22日
約3日間に及ぶブース運営、先程終了いたしました!
•PHPの利用バージョン+フレームワーク
•バージョンアップのツラいところ
それぞれボードで皆さんから伺いました🙇♂️#phperkaigi pic.twitter.com/dGPGiXcKaL
「廊下」や懇親会で多くの方とお話しさせていただきました。自身の発表を聞いてくださった方々からも話しかけていただき、見た目で覚えてもらえるのは得だな〜と思いました。大吉祥寺.pm 2025での私の発表「【実演版】カンファレンス登壇者・スタッフにこそ知ってほしいマイクの使い方」を見直していたという登壇者の声も多く聞けてよかったです。
飲み物調達数のヨミが完璧だったのも印象に残っています。クロージングで言われていた通り、やはりオブザーバビリティは大事ですね。(これはどちらかというモニタリングの領域な気はしてます。ビールの消費推移が分かっても、それがなぜか?までは踏み込めないと思うので。)
懇親会後は3次会まで高円寺で飲んだ後、中野に戻って野生のPHPerを探しつつ、見つけられなかったので撤収しました。スマホなしで探すのが無理ゲーすぎて。
来年も開催されるならぜひ参加したいです。
2次会で
id:o0h さんに、「Xdebugって遅くなるから本番環境での利用が推奨されないけど、Observer APIをXdebugでも使っていい感じにできるんじゃないか?」と質問いただきました。私は現役PHPerではないのもあってその場ではちゃんと答えられなかったので調べてみました。
Xdebugのソースコードを読んだのですが、v3からObserver APIを用いる実装になっているようです。zend_execute_exを用いる旧来の方法ではPHP 8のJIT下でキャプチャできないことがあるため、必然かもしれません。
static zend_observer_fcall_handlers xdebug_observer_init(zend_execute_data *execute_data)
{
return (zend_observer_fcall_handlers){xdebug_execute_begin, xdebug_execute_end};
}
XdebugはすでにObserver APIを用いているため、Observer APIを用いることによるパフォーマンス最適化の余地はない、というのが質問への回答になります。
次のカンファレンス参加は、2026-04-11(土)に開催されるPHPカンファレンス小田原2026の予定です。コアスタッフとして皆さまの参加をお待ちしております。
また、次のカンファレンスの登壇は、2026-05-14(木)・2026-05-15(金)に行われるクラウドネイティブ会議の予定です。今回もオブザーバビリティネタで、「ユーザー体験を可視化する非同期処理の分散トレーシングとSLI計測:ジョブキューを跨ぐコンテキスト伝搬の仕組み」について話します。全員来てください。
詳しい解説は暇な時に書くとして、とりあえず結論構築を提示します。
ヘッダーツールバーの「ファイル」の中に「ページ設定」があるので選ぶ。

デフォルトだと「ワイドスクリーン(16:9)」になっているものを「カスタム」にする。その後、単位を「ピクセル」に変えて以下のように設定。

毎回設定するのは面倒なのでテンプレを変えておきましょう。
qpdfの導入はこちら(Homebrew使用)。
$ brew install qpdf $ qpdf --version qpdf version 12.3.2 Run qpdf --copyright to see copyright and license information.
PDFファイルの正規化は以下のコマンドで実行できる。
$ qpdf --qdf ~/Downloads/Slide.pdf ~/Downloads/Slide_qpdf.pdf
生成されたSlide_qpdf.pdfをSpeakerDeckにアップロード。

ここが1920 × 1080になっていることと、生成された画像に文字化けが発生していないことを確認しよう。
取り急ぎ書いたので不正確な内容を含むかもしれません。
GitHub ActionsでAWS Lambdaのコンテナイメージをビルドしていて、かつ、buildxを使用していなかった(たとえばdocker/build-push-actionを使っておらず、docker build -t hogehogeというようにbuildxでないコマンド実行している)場合は問題が起きる可能性があるので読んでください。
2026年2月のGitHub Actionsのランナーイメージアップデートで、これに含まれるDockerのバージョンが29系に変わりました。
Docker Engine v29では、新規インストール時にcontainerdベースのイメージストアを使用するようになっています。アップデートでは明示的に設定しない限りこの変更が起こりませんが、仮想化されたCI環境はクリーンなので、containerdベースのイメージストアを使用するようになっているでしょう。
この関係か、docker buildによってできたイメージのmanifestフォーマットがOCIのもの(application/vnd.oci.image.index.v1+json)になります。この形式のmanifestにLambdaは現在対応しておらず、このイメージを指定してデプロイしようとすると以下のようにエラーになります。
InvalidParameterValueException: The image manifest, config or layer media type for the source image 0123456789.dkr.ecr.ap-northeast-1.amazonaws.com/hoge:poyo is not supported
回避方法としてはビルド時に--provenance=falseオプションをつけましょう。
build-push-actionのv4以降を使っている人はprovenanceの設定がデフォルトでtrueになっているので、今回のGitHub Actionsランナーのバージョンアップより前のタイミングですでに気づいて設定を見直しているはずです。
2026/02/20 追記:
GitHub ActionsイメージのDockerのバージョンアップデートがロールバックされたようです。
Due to the magnitude of the impact, we've decided to roll back to the image version with the previous major Docker version. The rollout is already in progress and will take up to 24 hours. This applies to both Ubuntu images.
https://github.com/actions/runner-images/issues/13474#issuecomment-3928452506
2026年1月20日のOpenTelemetryコレクター v1.50.0/v0.144.0のリリースノートにこのようなことが書かれていました。
exporter/otlp_grpc: Renameotlpexporter tootlp_grpcexporter and add deprecated alias otlp. (#14403)
exporter/otlp_http: Renameotlphttpexporter tootlp_httpexporter and add deprecated alias otlphttp. (#14396)
OpenTelemetryコレクターからOTLP/gRPCでテレメトリーを送信するにはOTLP/gRPC Exporterを利用し、このとき、これまでは設定ファイルのexporter欄にotlpというキーで設定を記述していました。このとき、これからはotlpではなくotlp_grpcと書くのが正しく、古い名前が非推奨となる、と書かれています。OTLP/http Exporterの場合も同様にotlphttpからotlp_httpに名前が変わります。
exporters: # これまで otlp: endpoint: backend:4317 # OTelCol v0.144.0以降は otlp_grpc: endpoint: backend:4317
なぜこのような変更がなされたのか、背景を追ってみましょう。
以下のIssueにこの件に関する議論があります:
これまで、コンポーネントの命名は以下の2パターンに分かれていました:
memory_limitertail_samplingotlphttpawsxrayresourcedetection現時点では後者のパターンのほうが多いように感じます。Go言語の慣習でパッケージ名をアンダースコアで区切らないことに引きずられているのでしょう。
このような命名規則に一貫性がない状態では、エンドユーザーから見て分かりにくいという問題意識がありました。
議論を経て、エンドユーザー目線での設定の読みやすさの観点などから、アンダースコア区切りを慣習とする採択がされました。また、既存のコンポーネントに関してもこの規約に従うように改名するが、下位互換性のためaliasとして古い名前でも利用できるようにするべきとされました。OpenTelemetryコレクターのコーディングガイドラインにもこの内容が反映されています*1。
その結果、まずはopen-telemetry/opentelemetry-collectorリポジトリに存在するコンポーネントについて、新しいコンポーネント命名ルールに従って改名がなされたというのが、冒頭に挙げたリリースノートの内容になります。
公式で配布されているOpenTelemetryコレクターのイメージやバイナリを利用している場合は、使用しているバージョンを確認してください。v0.144.0より前の場合には特に何もすることはありません。
v0.144.0以上に上げた場合、OTLP Exporterの部分については基本的には同じ設定で動くと思われますが、起動時に以下のようなwarningログが表示されます:
2026-01-27T12:43:54.628Z warn builders/builders.go:40 "otlp" alias is deprecated; use "otlp_grpc" instead {"resource": {"service.instance.id": "4c83c942-49d5-4fad-a5f6-74a1b3c099ee", "service.name": "otelcol", "service.version": "0.144.0"}, "otelcol.component.id": "otlp", "otelcol.component.kind": "exporter", "otelcol.signal": "traces"}
メッセージ通りに設定ファイルで使っている命名を新しいものに変えて起動すると、warningが表示されないようになるはずです。
ocbで独自ビルドしていたり、サードパーティでビルドされているOpenTelemetryコレクターディストリビューションを利用していたりする場合には、依存しているotlpexporter、otlphttpexporterのバージョンを確認しましょう。v0.144.0以上ならば同様の対応が必要になります。ocbのmanifestファイルを見るのが一般的だと思います。
Mackerel OpenTelemetryコレクターで、すでに改名後のotlpexporter、otlphttpexporterをbundleしていることがわかる様子:
- gomod: go.opentelemetry.io/collector/exporter/otlpexporter v0.144.0 - gomod: go.opentelemetry.io/collector/exporter/otlphttpexporter v0.144.0
既存のコンポーネントについて新しい命名に移行する方法がコーディングガイドラインに記載されているので、これに従いましょう:
- SHOULD add the lower_snake_case name as the primary identifier
- MAY support the old name as a deprecated alias for backwards compatibility
- MUST document the migration path in their README
古い名前を非推奨なaliasとしてサポートするには、コンポーネントのFactoryを生成するところで以下のようにoptionを渡す必要があります:
func NewFactory() exporter.Factory {
return xexporter.NewFactory(
metadata.Type,
createDefaultConfig,
+ xexporter.WithDeprecatedTypeAlias(component.MustNewType("mackerelotlp")),
xexporter.WithTraces(createTraces, metadata.TracesStability),
xexporter.WithMetrics(createMetrics, metadata.MetricsStability),
)
}
open-telemetry/opentelemetry-collectorリポジトリだけではなく、open-telemetry/opentelemetry-collector-contribに含まれるコンポーネントでも同様に改名していく動きが進んでいくものと思われます。
実際に、改名に対応するためのIssueがすでに作られています。ルールに従った新しい命名の案が表で出されているのが興味深い情報でした。
prev:
今年は結構色々出会いもありイベントもありで楽しかったんだけど、その分大分メンタル削ってしまった。来年は引きこもりたい。
仕事であんまりエンジニアリングしてないので、あんまり何かを新たに身につけたという感じがしない。
サブディレクターとして、プロダクトに軸足を置きつつ他部署に片足を突っ込む感じ。テックリードも引き続きやっている。
決断バジェットを消費しすぎて最近は燃え尽きたように仕事をしている。
エンジニア成分が半分になったので登壇も半分になった。異なる業界の方と一緒に登壇する機会を頂けたのはかなり良かった。
大阪、京都、名古屋、福岡、沖縄あたり。福岡は2回行ったのもあって向こうで顔見知りな人もできていい感じ。また行きます。
沖縄も人生初ダイビングできて相当良かった。
買い物としては可愛い靴を買ったぐらい。
地元のららぽーと行ったらやっといくつかピンとくる靴に出会えてとりあえず一つ買ってきた pic.twitter.com/oWFgAZgQqF
— Arthur (@Arthur1__) 2025年9月25日
髪色は金→赤→ピンク→青。
一番でかい買い物はDJ機材を一通り揃えたこと。
ということで、おうちでDJ環境整いました✌️✌️ pic.twitter.com/ehdBqC2c9h
— Arthur (@Arthur1__) 2025年7月22日
Switch 2も出遅れつつちゃんと買えました。
変化なし
ポケモンカード。PJCSは4-3。自主大会はいくつかトナメ上がってるけど公式大会は結構微妙、、、来年頑張ろう。
近所のミュージックバーに入り浸るようになって昨年比の30倍ぐらい楽器を弾いた。
DJも始めた。
売れ残りを自覚してまた一つ上のステージへ。
週末の準備OK。みんな小田原きてね pic.twitter.com/yJtddR3Ywf
— Arthur (@Arthur1__) 2025年4月9日

#RETEMPEST 2025-10-15 at Shibuya Milkyway w/ミスミ pic.twitter.com/w7xvscPlK3
— Arthur (@Arthur1__) 2025年10月15日
【バニー有】メンコンキャストシティ最弱0-6ソウブレイズ【ほぼ全文有料】 pic.twitter.com/BZqdEtEhi2
— Arthur (@Arthur1__) 2025年10月25日
ぼくより弱い人@Arthur1__ pic.twitter.com/6nPeUsDj5X
— 先生 (@new_sushi_) 2025年11月1日
誕プレazms https://t.co/jja7D0N6m7 pic.twitter.com/bNU6PxiFKl
— Arthur (@Arthur1__) 2025年11月21日
ポスト前後しちゃった🫠髪色に合わせてネイルも青くしたよ🔷🔷 pic.twitter.com/1eMVCM5QOr
— Arthur (@Arthur1__) 2025年12月31日
Go言語でOSSを開発しているみなさん、go.modのgo directiveにはどのような値を指定していますか?もしGo 1.25が最新のメジャーリリースである2025年12月現在で
go 1.25.0
と書いているならば、この機会にぜひ
go 1.24.0
に改めてくれないか、という話をします。同じような話はいろんなエントリや登壇で触れているのですが、この話題に主題を絞って解説します。
Go言語では半年に1回メジャーリリースがやってきます。今年(2025年)は2月11日にGo 1.24.0、8月12日にGo 1.25.0がリリースされています。
そして、security fixなどのサポート対象となるメジャーリリースは新しいもの2つ分となっています。2025年12月現在、サポートされているGoのメジャーリリースは1.24・1.25の2つです。来年2026年の2月にGo 1.26.0がリリースされたら、Go 1.24はサポートが終了するという流れです。
Each major Go release is supported until there are two newer major releases. For example, Go 1.5 was supported until the Go 1.7 release, and Go 1.6 was supported until the Go 1.8 release.
https://go.dev/doc/devel/release#policy
go.modのgo directiveにはGoのバージョンが指定されます。これは単に使用するGoのバージョンを表すのではなく、そのモジュールが要求するGoの最小バージョンを意味します。
The go directive sets the minimum version of Go required to use this module. Before Go 1.21, the directive was advisory only; now it is a mandatory requirement: Go toolchains refuse to use modules declaring newer Go versions.
https://go.dev/ref/mod#go-mod-file-go
さて、冒頭の問題提起である、2025年12月現在において
go 1.25.0
という宣言でどう困るかという話をします。
go directiveはビルド下限を表すので、そこに最新のメジャーリリース系統のバージョンを指定していると、それ未満のバージョンではそのmoduleをビルドできなくなります。そして「それ未満のバージョン」には、Goとしてサポート対象となっている1つ前のメジャーリリースが含まれます。すなわち、まだGo公式によってサポートされているGoのツールチェーンなのにもかかわらず、そのmoduleのビルドには利用できなくなってしまいます。
Go側でサポートされているGoのメジャーリリース2つをそのままサポート対象とするOSSはそれなりに多く見られます*1。例として、opentelemetry-goの互換性に関する記述を挙げましょう:
OpenTelemetry-Go ensures compatibility with the current supported versions of the Go language
https://github.com/open-telemetry/opentelemetry-go?tab=readme-ov-file#compatibility
ここだけ見ると、「いや、このModuleは最新のバージョンしかサポートしないので」というポリシーならば許容できそうですが、実は思ったよりその選択の影響は大きいのです。
先ほどの問題は、goディレクティブが新しすぎるModuleそのもののビルドに留まらず、そのModuleに依存するModuleにも波及します。
外部のGo Modulesに依存したライブラリModuleを作るとします。また、Go言語としてサポートされている2つのメジャーリリースはこのライブラリでもサポート対象とすることにします。
このとき、依存先のmoduleでgo 1.25.5と宣言されているならば、依存元のmoduleでもgo 1.25.5以上にしなければなりません。自分の作ったライブラリでGo 1.24をサポートしたくなっても、依存先の事情に引きずられてしまうわけです。この場合、依存先のmoduleを古いバージョンにしたり、あるいは依存先のModuleの利用を諦めたりしなくてはなりません。
この問題に関しても、module内のpackageが外部から参照されないようにinternal/配下に押し込むなどすれば許容できそうですが、さらにもう一つ落とし穴があります。
Go 1.24からgo.modにtool directiveが追加され、開発に必要なツールの依存を管理できるようになりました。tools.goを用いたワークアラウンド*2を利用せずとも、Go製のツールとそのバージョンを管理し、実行することができます。
なんと、依存先のgo directiveの影響を依存元が受けてしまう問題がtoolにおいても発生します。
たとえば、GoReleaserのgo directiveはv2.13.1現在でgo 1.25.5と宣言されています*3。最新のGoReleaserを以下のようにtoolに含めてしまうと、そのmoduleのgo directiveは1.25.5未満に設定することができなくなります。
go 1.25.5 // 1.24.0にはできない tool https://github.com/goreleaser/goreleaser/v2 require ( github.com/goreleaser/goreleaser/v2 v2.13.1 // indirect ... )
このように、ライブラリではなくツールの提供だけを目的としたModuleでも、go directiveが新しすぎることにより依存が困難になってしまうケースがあります。
go directiveはビルド下限を表すので、基本的には現在公式でサポートされているGoのバージョンはカバーするように宣言して欲しいです。
Go 1.25が最新のリリースである現在では、以下のように(あるいは以下よりもっと古くなるように)宣言して欲しいです:
go 1.24.0
なぜ1つ前のメジャーリリースの中で最新のパッチであるgo 1.24.9ではなくgo 1.24.0を指定した方が良いのでしょうか。
この理由は、同様の内容がgolang.org/x配下のmoduleのgo directiveを自動更新するproposalの中に書かれていて共感したので引用します:
Another option would be to always use the latest 1.(N-1).X, updating all the x repos each time a new minor Go release comes out. That forces everyone to update to that new minor release in order to incorporate any new x repo changes, which seems too aggressive. As much as we try to avoid it, minor Go releases do sometimes contain bugs, and it should be possible to choose to use older ones if needed.
要約すると、新しいパッチバージョンへのアップデートを強制するのは強引なので選択の余地を設けたということです。ある時点で最新のパッチバージョンにバグが含まれていないとも限りませんから。
ここからは、go.modのgo directiveに古いメジャーリリースを指定しておくことにより発生するデメリットと、それに対してどうハンドリングしたらいいのかについて説明します。
Go言語のメジャーリリースには毎回嬉しいアップデート入っているように私は思います。しかし、go directiveを1つ前のメジャーリリースに保つということは、最新の言語機能を利用することはまだできないということになります。
この問題に対して、私は残念ながら諦めています。Goのメジャーリリースが出ても、この機能はあと半年後に使えるようになるな〜ぐらいのつもりで向き合っています。
もちろん、メジャーリリースが出たタイミングで2つ前のメジャーリリースがサポート対象から落ちるため、このタイミングで1つ前のメジャーリリースの言語機能が新たに利用可能になります。リリースにワイワイするタイミングは同じで、その対象が1つ遅れているだけです。
actions/setup-goのgo-version-file inputにgo.modファイルを指定することでCI環境のGoのバージョンを決めているケースがあるでしょう。
- uses: actions/setup-go@v6 with: go-version-file: go.mod
setup-goはgo.modのgo directiveを読んで、その値と一致するGoのバージョンを利用する*4ため、go directiveが最新でないと古いツールチェーンがビルドやテストで利用されてしまいます。
これに対する対応としては、go.modのtoolchain directiveを利用するのが良いと思います。toolchain directiveは「そのモジュールで推奨されるツールチェーンとそのバージョン」を宣言するものです。
A toolchain directive declares a suggested Go toolchain to use with a module.
https://go.dev/ref/mod#go-mod-file-toolchain
setup-goのv6から、go.modのtoolchain directiveも読んでバージョンを決定するように、かつこの挙動がgo directiveの参照よりも優先されるようになりました。
よって、以下のようなgo.modを用意することで、go directiveを1つ前のメジャーリリースバージョンに保ちつつ、GitHub Actionsで使われるGoのバージョンを別に指定することが可能です:
go 1.24.0 toolchain go1.25.5
toolchain directiveはRenovateの標準設定で継続的に更新することができるため、最新に保つ労力が少ないのも魅力です。
In go.mod, the toolchain directive essentially means "Use this exact version of go". Unlike the go directive, it's valid to keep bumping this, and you should see updates to it proposed by default.
https://docs.renovatebot.com/modules/manager/gomod/#updating-of-go-mod-and-toolchain-directives *5
さて、いよいよ2026年2月にGo 1.26のリリースが控えています。現時点でもすでにドラフトのリリースノートを閲覧することができます。
このリリース予定の内容のひとつに、go mod initコマンドで作られるgo.modファイルのgo directiveの値が1つ古いメジャーリリースのバージョンになるというものがあります。
go mod init now defaults to a lower go version in new go.mod files. go mod init using a toolchain of version 1.N.X will create a go.mod file specifying the Go version go 1.(N-1).0.
https://go.dev/doc/go1.26#go-command
これまでgo mod initを実行した時には、使用しているツールチェーンのバージョンがそのままgo directiveにセットされていました。
$ go version go version go1.25.5 darwin/arm64 $ go mod init hoge go: creating new go.mod: module hoge $ cat go.mod module hoge go 1.25.5
これが、以下の挙動になるイメージです(実際にGo 1.25.5でこのようになるわけではなく、あくまでイメージです):
module hoge -go 1.25.5 +go 1.24.0
この変更理由について、リリースノートには「現在サポートされているGoのバージョンと互換性のあるモジュールの作成を奨励するため」と書かれています。
This is intended to encourage the creation of modules that are compatible with currently supported versions of Go.
https://go.dev/doc/go1.26#go-command
Goチームによるこの変更意図を読んでも、やはりgo directiveを最新ではなく1つ前のメジャーリリースに保つことに相当の妥当性があると考えられるでしょう。
go.modはgo directiveはGo Moduleのビルド下限を表すものです。また、go directiveにより宣言された下限バージョンは依存元に伝播していきます。go directiveを最新のバージョンで指定してしまうと、Goがサポートしているバージョンを利用しているにも関わらずビルドできないModuleになってしまいます。そしてそれが伝播してどんどん世の中に増えてしまいます。
外部から依存され得るGoのOSSプロジェクトでは、go directiveを最大でも1つ前のメジャーリリースにしてみませんか?バイナリが成果物の場合にはtoolchain directiveを利用して推奨ツールチェーンを宣言し、ビルド下限バージョンと利用するバージョンを分離して宣言してみませんか?というお話でした。
*1:[要出典]と言われても仕方がないですね。n=1ですがGo本体にもcontributeするようなOSSメンテナーの意見を置いておきましょう。https://github.com/golang/go/issues/74748#issuecomment-3115320682
*2:https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md
*3:https://github.com/goreleaser/goreleaser/blob/706905505d944237c24baff543def8800f295c2c/go.mod#L3
*4:setup-goがgo directiveの宣言と一致するバージョンを選択する挙動はgo directiveのセマンティクスを考えると微妙な気がしますが、かなりの破壊的変更となるためなかなか変えられないのでしょう。
*5:この引用において、"Use this exact version of go"という表現がされていることには若干の引っ掛かりを覚えています。仮にtoolchain go 1.25.0と書かれていて手元のツールチェーンのバージョンが1.25.5だとしても、ダウングレードせず1.25.5で動くのが標準(GOTOOLCHAIN=auto)の挙動ですから。