header background image

GitHub Actionsで仕様書の更新漏れを“仕組みで止める”——gh-awで自動PR/NoopするPoC

2026年2月11日☕️☕️☕️ 13 min read

tl;dr

  • 仕様書の更新漏れは注意力では止まらない
  • 基本は「PRと一緒にdocs更新」だが、それでも漏れるので“二次防衛”が必要
  • gh-awで「docs更新が必要ならPR / 不要ならnoop」を自動化すると、人間のレビューが“楽”になる
  • 詰まったのは2つだけ:Safe OutputsActions の PR 作成権限
  • ついでにPR文面を日本語&Draft解除まで整えると、運用のストレスが消える

背景:ドキュメントは「気をつける」だけだと必ずズレる

昔も今も、避けて通れない課題が 仕様書の管理
コードだけ更新されて 仕様書や手順書が古いまま――これは日常的に起こります。

しかも AI時代はこれが悪化しやすい
AIが素早くソースコードを生成・変更できるほど、更新の回数と速度が上がり、結果として ドキュメントが置いていかれる確率 も上がります。

ここで「気をつける」で勝つのは無理ゲー。
なので、差分を自動検知して、更新漏れが起きにくい導線を先に作る方が現実的です。

当然、いちばん綺麗なのは コード変更のPRにdocs変更も同梱すること。
実際うちも普段はこの運用をしています(レビューも差分も1箇所で済む)。

ただ、それでも漏れる。

  • レビューが忙しい日
  • 変更が想定より広く影響した日
  • AIが高速にコードを変えて「追従タスク」が増えた日

こういう日には、“正しいコード”がそのまま通って、docsだけ置き去りが起きる。
だから今回は「PRで直す」を否定せずに、漏れた時に自動で気づける二次防衛を足す、という立て付けにした。


事故はいつも「コードは正しい」顔をしてやってくる

送料計算のロジックを変えた。

  • コードは動く
  • テストも通る
  • PRもマージされた

……のに、仕様書だけが古いまま残った。

別に珍しくない。むしろ“よくある”。
だから「ちゃんと書こう」ではなく、ズレると勝手に止まる方向に寄せたくなった。

今回はその緩和策として、GitHub Agentic Workflows(gh-aw) を使い、

  • src/ などの変更をトリガーにする
  • 影響する docs を見直す
  • 更新が必要なら PR を自動作成する
  • 何も不要なら noop で「何もしなかった」を明示する

という流れをPoCとして組みます。

ここでやりたいのは「ドキュメントを完璧に自動生成」ではなく、
更新漏れを“見逃しにくくする仕組み” を作ることです。


方針:一次防衛(PRで直す)+二次防衛(漏れたら自動で止める)

  • 一次防衛:PR時点でdocsも更新する

    • いちばん綺麗。差分もレビューも1回で終わる。
  • 二次防衛:それでも漏れたら、main への push をトリガーに“後追いPR”を自動生成する

    • 「漏れたのに静かに進む」を避ける。
    • 直す必要がなければ noop で「動いたが何もしなかった」を残す。

今回のPoCはこの 二次防衛 を“仕組み”として用意する話です。


gh-awでやりたかったこと(人間のレビュー観点をそのまま機械に渡す)

狙いはシンプル。

  1. src/ の変更をトリガーにする
  2. 影響する docs を見直す
  3. 直す必要があれば PR を出す
  4. 直す必要がなければ noop で明示する

ここでポイントは、「AIが賢いから全部見つけてくれるはず」ではなく、

人間がレビューでやっている判断を、毎回同じ手順で再現させたい

という思想。


1回目:検知したのに成果物ゼロ(No Safe Outputs)

最初の実験、面白いことが起きた。

AIは「仕様書更新が必要」と判断した。
ログにもそれっぽい“完了サマリ”が出る。 この“完了サマリ”は人間向けの文章で、PR作成などの実行には safe outputs の structured output が別途必要。

……のに、ワークフローは失敗する。

no-safe-outputs.png

理由はこう:

Safe Outputs が生成されていない
(No Safe Outputs Generated)

ここで一瞬「え、AIが作業したのに何がダメなの?」ってなるんだけど、gh-awの設計を理解すると納得する。

  • エージェント本体は基本 read-only
  • 書き込み(PR作成など)は safe outputs 経由で“明示”しないと反映されない

つまり、AIがローカルで「コミットした気分」になっても、それは成果物としては無効

そこで指示をこう変えた。

  • 変更があるなら create-pull-request を必ず呼ぶ
  • 変更がないなら noop を必ず呼ぶ
  • コミットは禁止(成果物は safe outputs で出す)

2回目:PRを作ろうとして権限で死ぬ

次は create-pull-request を呼ぶようになった。

今度こそ勝った……と思ったら、別の地雷。

GitHub Actions is not permitted to create or approve pull requests.

これ、コードじゃなくて GitHub 側の設定

Actions の「Workflow permissions」が読み取りのみだと、PR作成が通らない。
つまり、

仕組みは合ってるのに、権限が足りなくて死ぬ

という、CIあるあるに着地する。

ここは UI で2つONにしたら終わりだった(後述)。


最終形:PR/Noopを強制し、日本語で、DraftじゃないPRを出す

ここまで来ると、「動く」だけじゃなくて「運用が気持ちいい」状態に寄せたくなる。

  • PRが Draft だと、地味にダルい
  • PRの説明が英語だと、地味に読み飛ばす
  • 変更がないのに黙って終わると、「動いたのか?」が分からない

なので、最終形はこう。

  • docsを直したら PR(Ready for review) を出す
  • 直すものがなければ noop を出す
  • PRタイトル&本文は 日本語
  • 変更対象は /docs と README のみ(ソースは絶対いじらない)

最終的に docs-auto-fix.md はこの形になっていて、かなり“運用できる”と思う:

補足:本来はPRトリガーで“マージ前に直す”のが理想。
ただ今回は「普段はPRでやってるのに、それでも漏れた」を潰すために、main への push を二次防衛のトリガーにしている。

.github/workflows/docs-auto-fix.md
---
on:
  push:
    branches:
      - main
    paths:
      - "src/**"
      - "test/**"
      - "package.json"
      - "tsconfig*.json"
      - "nest-cli.json"
permissions:
  contents: read
  issues: read
  pull-requests: read
safe-outputs:
  create-pull-request:
    draft: false
  noop:
    max: 1
tools:
  edit:
---
# Docs Auto-Fix

## Goal
Keep documentation in `/docs` and `README.md` consistent with recent source code changes.

## Instructions
1. Identify what changed in this push (check the git diff or review the modified files under `src/`, `test/`, and config files).
2. Determine which docs are impacted and update them for accuracy.
3. Only modify documentation files under `/docs` and `README.md`. Do not change source code.
4. Do NOT commit directly. If documentation updates are made, use the safe output tool `create-pull-request` to propose changes.
5. If no documentation updates are needed, use the safe output tool `noop` to explicitly report no action.
6. When creating a pull request, write the PR title and body in Japanese. Include a short summary and test status.
7. Keep updates minimal, precise, and aligned with existing formatting.

## Repo Notes
> Note: "Repo Notes" is an in-prompt memo to pin SSOT locations, not a built-in gh-aw feature.

- If shipping fee rules or API behavior change, update `/docs/shipping-fee-spec.md`.

docs更新が必要な場合は create-pull-request が走ってPRが作られる(下図)。

success.png


導入手順(コピペ用チェックリスト)

ここが一番つまずきやすいので、設定も含めてチェックリスト化した。

1) ファイルを追加する

  • .github/workflows/docs-auto-fix.md を作る(上の内容)

2) lock を生成する

gh aw compile

生成される .github/workflows/docs-auto-fix.lock.yml も 必ずコミット

3) GitHub Actions 側の設定(ここで死にがち)

Repo → Settings → Actions → General で:

  • Workflow permissions: Read and write permissions
  • Allow GitHub Actions to create and approve pull requests: ON

これがないと create-pull-request が権限エラーで落ちる。

4) Secret(Copilot を使う場合)

Repo → Settings → Secrets and variables → Actions → New repository secret

  • COPILOT_GITHUB_TOKEN を追加

(Fine-grained PAT で “Copilot Requests” を付ける。最小権限でOK、という設計に寄せるのが気持ちいい)

5) 動作確認

  • src/ 配下を触って main に push
  • docs更新が必要なら PR が出る
  • 必要ないなら noop が出る(「動いたけど何もしなかった」が可視化される)

教訓:「気をつける」より「通らない仕組み」

今回いちばん面白かったのはここ。

  • AIは“判断”できる
  • でも、成果物として反映するには儀式が必要(safe outputs)
  • そして、権限は現実(Actions の PR 許可)

つまり、AIに全部任せるというより、

“AIが動けるレーン”を人間が設計してあげる

のが勝ち筋だった。

そしてそのレーンが一度できると、仕様書の更新漏れは「注意力」じゃなくて「仕組み」で減らせる。

速度が上がる時代ほど、ズレも増える。 だから「ちゃんと書こう」ではなく、PRで直す(一次防衛)+漏れたら自動で炙り出す(二次防衛) を先に作る方が、多分うまくいく。

サンプルリポジトリ:

https://github.com/thundermiracle/ai-auto-docs

ThunderMiracle

Blog part of ThunderMiracle.com

コメントは表示領域に入ると読み込みます