自動で立てたIssueがslug改名で自動クローズされずに残る穴を塞いだ
今回やったこと
画像生成を後段へ回す自動化では、記事が画像待ちになった時点で依頼Issueを作り、生成物がそろったら公開処理の後段でIssueを閉じる。ここで記事の slug を、依頼と記事を結び付ける識別子として使っていた。公開前後に slug が改名されると、記事自体は存在するのに、Issueを閉じるための鍵だけが失われる。
結果として、画像生成が完了しても未処理のIssueが残り続ける。人間から見ると同じ記事でも、自動処理から見ると「古いslugの依頼」と「新しいslugの記事」が別物になるためだ。今回の修正では、画像依頼・生成から公開昇格に至るまでの識別子の受け渡し経路を見直した。
slugは表示名であって安定したIDではない
slugはURLやファイル名に使いやすく、記事を探すには便利である。一方で、編集判断によって変わり得る。タイトルを短くしたり、表記を揃えたり、公開前に検索向けの名前へ変更したりする運用では、slugが永続識別子だとは限らない。
| 用途 | slugの適性 | 理由 |
|---|---|---|
| URL・記事の見た目 | 高い | 読者が辿る名前として分かりやすい |
| ファイル名 | 高い | 作業対象を一覧しやすい |
| 非同期Issueの永続的な対応付け | 低い | 改名で過去の鍵が変わる |
| 状態遷移の内部ID | 低い | 表示名と識別子の責務が混ざる |
問題は、slugを使ったこと自体ではない。変更される可能性のある表示名を、閉じる処理の唯一の鍵にしたことにある。画像生成はその場で完結する処理ではなく、依頼作成、生成、rawへの保存、レビュー、公開という複数の段階をまたぐ。その間に名前が変わるなら、状態を追跡する別の軸が必要になる。
依頼と公開を別の状態として扱う
まず、画像依頼Issueの状態と、記事の公開状態を同じものとして扱わない。Issueは画像を生成・添付する作業の状態を持ち、記事は ready、deploy、journalなど別の昇格状態を持つ。記事が公開されたからといって、Issue側の対応関係をslugの再計算だけで探す設計にすると、改名で切れる。
今回の対象では、画像生成スクリプト、起稿手順、公開昇格スクリプトをまとめて確認した。依頼時に残す情報、生成物が置かれる場所、公開後に閉じる対象をそれぞれ確認し、slugの変更後も元の依頼へ戻れる情報を使うように経路を修正した。重要なのは、Issueのタイトルを人間向けに読みやすくすることと、機械が対応関係を解決することを分離することだ。
コードだけを直して終わりにしないため、生成・昇格・テストを同じ前提で揃える。生成側が新しい識別方法で記録しても、昇格側が古いslug検索を続ければ、見かけ上は直ったように見えて実運用で残る。反対に、閉じる処理だけを変更しても、過去の依頼に必要な情報が保存されていなければ対応できない。
自動化で名前を使うときの確認項目
記事や画像の処理に名前を使う場合、少なくとも次の境界を確認する。
- その名前は人間の編集で変わるか。
- 非同期処理が終わるまで、同じ値を保証できるか。
- 名前を変えた後も、過去の依頼を検索できるか。
- 依頼作成・生成・昇格・クローズの全段階が同じ識別規則か。
- 対応付けに失敗したとき、未処理として見えるか。
最後の点も重要である。閉じる対象が見つからないときに成功扱いにすると、Issueだけが積み残される。自動化の出口では、対象が見つかったこと、状態が変わったこと、変えられなかったことを分けて記録する必要がある。
やってみてわかったこと
人間には同じ記事に見える名前の変更が、無人処理では状態遷移を壊す。特に画像生成のような非同期処理は、依頼した時点と公開する時点が離れるため、表示名を内部IDに流用すると問題が後から現れる。
対策は、slugの変更を禁止することではない。slugはURLやファイル名として変更可能なままにし、Issueと記事の対応には変更されない情報を持たせることだ。そして、生成・昇格・テストのすべてがその情報を使うようにする。名前は読者と人間のため、識別子は状態機械のため、と責務を分けると、改名が自動化全体の破綻条件にならない。
実装ステータスと更新履歴
実装済み・稼働中。参照した実装は、画像生成・自動起稿・公開昇格を担うスクリプト群である。
- 更新履歴: 2026-09-12 初稿。
- 訂正履歴: なし。