Quartet / Quintet

2026-09-07  ·  zenn · github · markdown · 個人開発 · claudecode

Zenn の「投稿数の上限に達したためデプロイされませんでした」で実際に起きていること

GitHub 連携で記事を push しました。デプロイは成功しています。

それでも記事が出ません。ダッシュボードにだけ、こう出ています。

デプロイ成功
9ファイルの更新

2件のお知らせ
次の記事は投稿数の上限に達したためデプロイされませんでした:
  ai-code-review-not-theater, composite-github-action,
  verification-that-verifies-nothing, what-belongs-in-claude-md

原因の切り分けに丸一日使ったので、分かったことを全部置いておきます。

先に結論だけ書きます。

1. どこにも書いていない、という前提を先に受け入れる

ここで一番時間を溶かしました。

git push は成功します。Zenn 側のデプロイも「成功」と表示されます。 GitHub の commit status を見ても、check-runs を見ても 0件です。

$ gh api repos/<owner>/<repo>/commits/<sha>/status --jq '.state, (.statuses|length)'
pending
0

$ gh api repos/<owner>/<repo>/commits/<sha>/check-runs --jq '.total_count'
0

Zenn は連携リポジトリに何も返しません。 成功も失敗も書き込まない。

なので、こちら側で観測できるのは「push できた」までです。 そこから先で何が起きたかは、ブラウザでダッシュボードを開かないと分かりません。

私はこの前提を疑わないまま、リポジトリの中身を疑いました。 二分探索でファイルを3つまで削り、frontmatter を最小にし、slug を変え、 ディレクトリ構成を作り直しました。全部無駄でした。

観測できない場所に理由が置かれている系では、手元の実験をいくら重ねても届きません。 ログを1行見る方が速い。

2. Zenn 側の仕様

Zenn の FAQ に説明があります。

ただし、この FAQ の本文は HTML に入っていません。 クライアント側で描画されるので、 curl で取ると外枠だけが返ってきます。

$ curl -s https://zenn.dev/faq/rate-limit | wc -c
   34976

$ curl -s https://zenn.dev/faq/rate-limit | grep -c '投稿数の上限'
0

35KB 返ってきているのに、本文の文字列は1つも含まれません。 返ってくるのはヘッダとフッタのリンクだけです。 検索から辿り着きにくいのは、たぶんこれが理由です。

ブラウザで開くと読めます。要点はこうです。

上限のロジック 非公開。「さまざまな要素を組み合わせたロジック」とだけある
記事 直近 24時間以内の投稿数で判定。投稿予約中のものも数に入る
直近 1週間以内で判定。記事とは独立した上限
スクラップ 上限は緩い
緩和 他サービスからの移行なら、問い合わせフォームから一時的な緩和を申請できる

数値そのものは公開されていません。そこは測るしかありません。

3. 測った値

新規アカウントで、12本を一度に push した日の実測です。

公開された 2本(04:40 UTC / 12:31 UTC)
同じ日に弾かれた 残り全部

つまり新規アカウントでは24時間あたり2本前後でした。 アカウントの状態で変わる可能性が高いので、この数字は目安です。

上限ちょうどで回すのは勧めません。 1回ずれただけで弾かれ、 弾かれたことに気づく仕組みが要ります。私は1日1本にしました。

4. 記事と本の上限は独立している = 同時に当たる

ここで一度、間違った結論を出しました。

記事1本と本1冊が同時に止まったとき、私はこう考えました。

記事と本の上限は独立しているのだから、記事の投稿数の上限では説明できない。 別の原因があるはずだ。

逆です。 独立しているというのは「片方が当たっても、もう片方は当たらない」ではなく、 **「それぞれ別に判定される」**という意味です。別に判定されるなら、 両方同時に当たることは普通に起きます。

実際そうでした。ダッシュボードには2件のお知らせが並んでいて、 片方が記事、もう片方が本でした。

観測は正しかったのに、そこから引いた結論だけが間違っていました。

5. 弾かれたものは、勝手には出てきません

これが運用上いちばん効きます。

弾かれた記事は published: true のまま残ります。 そして次にデプロイが走ったときに、もう一度判定されます。

裏を返すと、デプロイが走らない限り、上限が空いても出ません。

書き溜めた分を push し終えて、次に push する用事が無い状態がいちばん危険です。 上限が空いても、それを知らせるものが何も動きません。

私は空コミットを1日1回押すようにしました。

git commit --allow-empty -m "Retry the queued posts"
git push origin main

6. 更新は上限の対象外

これは救いです。すでに公開されている記事の更新は、上限に関係なく反映されます。

実測で 7秒でした。typo の修正や追記が止められることはありません。 止まるのは新しく公開されるものだけです。

7. 公開されたかどうかを RSS で見てはいけません

最後に、私がここで一度誤報を出した話を書いておきます。

再試行が通ったかどうかを、Zenn の RSS フィードで確認しました。 出ていなかったので「まだ弾かれている」と報告しました。

記事は公開されていました。 RSS の反映が遅れていただけです。

確認するなら記事の URL を直接叩いてください。 これは即座に切り替わります。

$ curl -s -o /dev/null -w '%{http_code}\n' \
    https://zenn.dev/<user>/articles/<slug>
200   # 公開されている
403   # まだ出ていない

未公開の記事は 403 を返します。404 ではありません。

で、どうするのがいいか

上限を回避する方法を探すのは、たぶん間違いです。

12本を一度に push した行為そのものが、「乱造」の形をしていました。

Zenn は AI コンテンツの方針で 「機械により自動生成された文章の投稿」と「AI生成による投稿の乱造行為」を禁止しています。 AI の利用自体は禁止されていません。求められているのは 人が主体となって発信すること=著者が内容を検証していることです。

中身が自分の実測だけで書かれていても、出し方が違反の形をしていたら同じに見えます。

レート制限は警告として機能したと考えるのが妥当で、 やることは回避ではなく、ペースを落とすことでした。

まとめると、運用としてはこうなります。


Claude Code に設計・実装・レビューを別々の人格として分担させ、GitHub Issue と ブランチを軸に並列開発を回すための設定一式を MIT で公開しています。 コピーして ./setup.sh を叩けば動きます。技術スタックには依存しません。

https://github.com/quintetkit/quartet

このワークフローだけで実際にツールを 1 つ作りました。Issue の分割から PR、 レビュー、マージまで記録が全部残っています。うまくいかなかった箇所も消していません。

https://github.com/quintetkit/mdlinkcheck

UI 設計人格・レビュー基準・Issue 単位の並列実行スクリプト・実践ガイド 10 章を 足したものは製品ページにあります。

この運用そのものを配っています

4 人格版 Quartet は MIT で無料公開しています。UI 設計人格・レビュー基準・ Issue 単位の並列実行スクリプト・実践ガイド 10 章を足した Quintet は有料版です。

無料版を見る 製品ページ