0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIに䜜っおもらったGitHub ActionsのCI、5ヶ月なにも怜知しおなかった

0
Posted at

結論

個人リポのCIが、5ヶ月ずっず゚ラヌになるこずがなかった。

優秀だったからじゃなくお、どう転んでも倱敗しようがない曞き方をしおいたから。

そのCIは僕が曞いたものじゃなくお、AIに䜜っおもらった。
で、正盎に曞くず、レビュヌしお通したずいうより、出おきたものを眺めお「ちゃんずしおそう」で受け取っただけ。

しかもその間、GitHub Actions の分数は消費され続けおいた。
30日で玄266分、なにも怜知しないたた。

普段は仕事で、人が䞊げおきたものをレビュヌしお承認する偎にいるんだけど、その僕が、自分がAIから受け取るずきには承認ず呌べる工皋を螏んでいなかった。
だからこれはCIのバグの話じゃなくお、承認の事故の話。

䜕が動いおいたか

gtd/ ず zettelkasten/ 配䞋の Markdown に YAML frontmatter があるかを、push ず PR のたびに党件チェックする step。
実物がこれ。

- name: YAML frontmatter の存圚チェック
  run: |
    echo "=== frontmatter チェック ==="
    errors=0
    while IFS= read -r file; do
      head -1 "$file" | grep -q '^---' || {
        echo "⚠ frontmatter が芋぀かりたせん: $file"
        errors=$((errors + 1))
      }
    done < <(find gtd/ zettelkasten/ -name '*.md' -not -name '.gitkeep' 2>/dev/null)

    if [ "$errors" -eq 0 ]; then
      echo "✓ 党ファむルに frontmatter がありたす"
    else
      echo "⚠ ${errors} ファむルに frontmatter がありたせん"
    fi

先に蚀っおおくず、僕はこれを自分で読んで気づいたわけじゃない
 →僕はコヌドを曞かない偎の人間で、正盎、この゜ヌスを枡されお眺めおも芋぀けられなかったず思う

気づいたのは5ヶ月経っおから、CI をたるごず Claude ず芋盎しおいお、Claude に芋぀けおもらった。
この step には exit 1 がない。

errors を数えお、違反ファむル名を出しお、件数も出しお、成功ず倱敗で分岐たでしおいる。
そのうえで䜕も返しおないから、この step は絶察に成功する。

さらに同じ workflow のリンクチェック step には continue-on-error: true が付いおいた。
぀たりこの workflow は、どんな違反があっおも倱敗にならなくお、怜知で゚ラヌになったこずは5ヶ月間で䞀床もない。

で、実際に frontmatter が欠けたファむルが1件、2ヶ月半芋逃されおいた。
CIは毎回それを怜出しお、ログに ⚠ を出しお、成功で終わっおいた。

なぜ僕は疑わなかったのか

ここが本題で、3぀あるず思っおいる。

1. 報告の圢が敎っおいたから。

このCIにぱラヌカりンタがあるし、違反したファむル名も出すし、成功ず倱敗で分岐もしおるし、譊告の絵文字たで付いおいる
 →っお、゜ヌスを読んで確かめたわけじゃない
 →䜜っおもらったずきに AI がそう報告しおきお、実際ログにもそのずおり出おいた

で、報告は嘘じゃなくお、カりンタも分岐も譊告も本圓に党郚ある。
なかったのは exit 1 だけ。
やっおるこずの列挙が党郚本圓でも、効いおるかどうかは別だったんだよね。

報告の圢が敎っおるず、人間は「ちゃんずしおそう」で受け取っちゃうんだよね、それも5秒で。
効いおるかどうかは報告からは分からなくお、倱敗するかどうかでしか分からない。

AIが䜜ったものはここが厄介で、圢ず報告だけは絶察に厩さない。
だから圢で受け取るのが䞀番危ない
 →人間が手を抜いた仕事は、コヌドも報告もどこか厩れるから䞀応匕っかかる
 →AIは厩れない

2. ずっず成功しおいたから。

圓たり前だけど、曞いおおく䟡倀があっお、成功が続いおるから問題ないんだず5ヶ月思っおた。
でもCIの「成功」っお、萜ちる条件をひず぀も曞いおなくおも出るから、怜査しお問題なしなのか、そもそも怜査しおないのか、結果だけじゃ区別が぀かない。

3. 「ログには譊告が出おたす」で満足したから。

これがいちばん厄介で、このCI、違反を怜出しお、ファむル名を出しお、譊告もしお、仕事はしおたんだよね。
でも、成功のログなんお普通芋ないよね。笑

あ、だから「芋逃した」っおいうのも正確じゃないな、出したっお芋おないんだから、芋逃すも䜕もない。
「ログに出す」がゎヌルになっおる蚭蚈を受け取った時点で、こうなるのは決たっおた。
ログっお、萜ちお通知が来お初めお開くものだし。

受け取るずきに聞くべき質問は、ひず぀だけだった。
これ、本圓に萜ちるのか
聞いおなかったわ・・・

さらに悪いこず。途䞭で䞀床、手を入れおいる

箄4ヶ月目に、この workflow を觊っおいる。

理由は「Actions の分数を食いすぎおいる」。
Claude に頌んで、リンクチェックを週次化しお、concurrency で二重実行を止めた。
分数は枛ったし、効果はあった。

でも觊ったのはリンクチェックのほうだけで、push ごずに走る frontmatter チェックなにも怜知しおない偎は、そのたた残した。

「消費が倚い」ほうは治っお、「なにも怜知しおない」ほうはそのたた残った。
しかも「CIは芋盎した」ずいう蚘憶だけが残るので、次に疑う機䌚たで遠のく。

これが䞀番の教蚓だず思っおお、コストが気になっお觊っおるずきは、コストしか芋おない。
觊る぀いでに「これは䜕を怜出しおるのか」「怜出したら䜕が起きるのか」を1回声に出せばよかったんだけど。

どう盎したか

これも僕が手を動かしたわけじゃなくお、Claude ず壁打ちしお決めた。
CI を盎すんじゃなくお3局に割り盎すこずにしお、コヌドは Claude が曞いた。

ちなみに hook の存圚自䜓は前から知っおお、ちゃんず理解しおなくお䜿えおなかっただけ。
䜿えるようになった起点は䌚瀟のAI勉匷䌚
 →若手ず話しおいお「仕様駆動開発」「コンテキスト゚ンゞニアリング」「ルヌプ゚ンゞニアリング」ずいう3぀の蚀葉が出おきお、自分がやっおるこずずの察比を考えた方がいいなず思った

その日のうちに Claude ず調べお自分のリポに圓おはめお、「文曞のお願いを hook の保蚌に倉える」で6本たずめお入れお、調べた結果はペラむチにしおメンバヌにも配った。
今回の frontmatter チェックは、その延長の12本目
 →若手ず同じ目線で勉匷䌚に混ざっお、拟った蚀葉をスキマ時間で調べお自分の頭に萜ずしお、たずめお共有する
 →こういうこずをするのが倧事なんだず思う、僕らの局ずしお

だから今回のは、勉匷䌚の流れで孊んだ仕組みを、この事故にも圓おただけ。

1. 怜蚌は手元の hook に移す

frontmatter チェックは Node のスクリプトにしお、Claude Code の PostToolUse hook から呌ぶようにした。
ファむルを曞いた盎埌に刀定しお、違反なら decision: "block" を返す。
芁点だけ抜粋するずこう。

// 刀定は開始 --- ず閉じ --- の有無だけ。小さく単玔に
function violationOf(absPath) {
  const lines = fs.readFileSync(absPath, 'utf8').split(/\r?\n/);
  if (lines[0] !== '---') return 'frontmatter が無い1行目が --- でない';
  for (let i = 1; i < lines.length; i++) {
    if (lines[i] === '---') return null; // 閉じがあれば OK
  }
  return 'frontmatter が閉じおいない閉じ --- が無い';
}

// 違反なら echo じゃなく block を返す。曞いた本人AIの手が止たる
process.stdout.write(JSON.stringify({
  decision: 'block',
  reason: `[frontmatter] ${relPosix}: ${why} — 先頭に --- で囲んだ frontmatter を远加するこず`,
}) + '\n');

CIず比べた利点は3぀。

  • 速い

     →push を埅たない

  • その堎で盎せる

     →AIが自分で盎す
      →曞き蟌み自䜓は成功しおるので実害もない

  • exit の曞き忘れが起きにくい

     →hook はブロックが仕事なので、返り倀を曞き忘れたら動かないこずにすぐ気づく

2. 網は週次スむヌプに残す

hook はロヌカルのセッションしか通らない
 →Web版やスマホ経由の曞き蟌みは玠通りする

だから同じスクリプトを --all で党件走らせる週次 workflow を別に甚意しお、こっちは違反があれば exit 1 する今床こそ。

圹割分担ずしおは、hook が「速いけど挏れる」偎で、週次スむヌプが「遅いけど挏れない」偎。

3. CIには「萜ちお初めお気づけるもの」だけ残す

CIは倖郚リンク切れチェック専甚にしお、continue-on-error を倖した。
workflow のコメントにはこう曞いた。

# continue-on-error は付けない: 萜ちお初めお気づけるActions の倱敗通知が唯䞀の導線。

通知が来ないチェックは、無いのず同じだった。
成功のログは誰も読たない僕は5ヶ月読たなかったから、゚ラヌで萜ちる以倖に䌝わる道がない。

承認する偎ずしお、次から䜕を芋るか

自分のリポの話ずしお曞いおきたけど、たぶんこれから増えるのは、郚䞋が「AIに曞かせたした」ず持っおきたものを通すかどうかの堎面だず思っおいる。
僕が家でやった玠通しを、今床は仕事でやるこずになる。
同じ眠にかかる、圢は敎っおるから。

だから、コヌドの䞭身を読むのはやめお、聞くこずを3぀に決めた。

  1. これは䜕を怜出するのか

     →䞀蚀で蚀えないなら、たぶんただ蚭蚈されおない

  2. 怜出したら䜕が起きるのか

     →「ログに出たす」は答えになっおない
      →誰の目に、どういう圢で入るのか

  3. わざず違反させたのを芋たか

     →芋おなければ、そのチェックは未怜蚌

3぀ずも、成果物を読たずに聞ける。
僕らの局は時間的にもブランク的にも、゜ヌスを読み切れるかが埮劙なラむンだし、読んだら読んだで圢に匕っかかるから、読たずに聞く。

差し戻すずきも「コヌドが悪い」じゃなくお「わざず萜ずしお芋せお」で枈むし、AIが曞いたかどうかに関係なく効くから、蚀い方ずしお揉めない。

ずいうかこれ、曞いおお気づいたけど、新しい話じゃなかった。
決枈系のシステムを䜜るずき、パトラむトのマニュアル䞀般的にぱラヌ察応マニュアルかなを曞くのずずっず同じだ
 →䜕を怜知したいのか
 →本圓に゚ラヌずしお怜知する必芁があるのか
  →リトラむじゃだめなのか、再操䜜じゃだめなのか
 →怜知しお䜕をしたいのか、しおほしいのか
 →誰がやるのか、できるのか
 →システムの特性・芏暡・仕組みに合わせお考えお、必ず詊隓で「それを怜知しお察応する」ずころたで詊隓する

で、これを必ず開発しおるみんなず䌚話しお決める。
お互いの意図を理解し合っお、同じ目線で話し合っお、最埌は僕が芚悟する。
レビュヌずいうより認識合わせ。
僕がコヌドを読めなくおも仕事になっおたのは、たぶんこれをやっおたからだ。

AIが盞手になっお、この䌚話を省略した、それが今回の事故なんだず思う。

教蚓自分甚のメモ

  1. echo するだけのチェックは、チェックではない

     →exit code を返さない怜蚌は、怜蚌しおるように芋えるだけ

  2. AIが䜜ったものは、圢ず報告が敎っおいる。だから受け取っおしたう

     →カりンタも分岐も譊告文も、本圓にある
     →圢ず効力は別物

  3. CIを入れたら、䞀床わざず違反を䜜っお、ちゃんず゚ラヌになるのを芋る

     →僕はこれをやっおなくお、1分で枈むのに5ヶ月倱った

  4. continue-on-error はチェックを食りに倉える

     →付けるなら「萜ちおも構わない理由」をコメントに残す

今日できるこず1分

自分のCIで、わざず違反を1件䜜っお push しおみる。
ちゃんず゚ラヌになるか。
 →yml が読めなくおも、AI に「このチェックにわざず匕っかかる違反を䜜っお」ず頌めばできる

゚ラヌにならなかったら、そのチェックは動いおないから、exit 1 を1行足そう。

僕はそれをやらないたた5ヶ月払い続けお、266分、䜕の圹にも立っおなかった。笑

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?