【Show HN】ブルコリ:クラウド上で動作するワンショットコーディングエージェント

2026/04/23 1:09

【Show HN】ブルコリ:クラウド上で動作するワンショットコーディングエージェント

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

Broccoli は、Claude や Codex などの AI モデルを用いて Linear チケットを GitHub プルリクエストへ変換し、サーバーレスアーキテクチャにより独自の Google Cloud Platform (GCP) 上でソフトウェア開発ライフサイクルを自動化します。システムは Postgres データベースを共有する 2 つの明確なワークロードを採用しています:

broccoli-oss-service
が Webフックと重複排除を管理し、
broccoli-oss-runner
が自動化タスクを実行します。デプロイには、請求機能付き GCP プロジェクト、認証された
gcloud
、Python 3.12 以降、Anthropic、OpenAI、GitHub、Linear 用の API キーといった特定の要件が必要です。セットアッププロセスには、GitHub App の作成、専用 Linear ボットユーザーの指定、これら認証情報を含む Google Secret Manager の設定、サービスをデプロイし安全な Webフック URL を生成するためのバースクriptの実行が含まれます。稼働すると、Broccoli はラベルやサイズ見積もりに基づいて問題をインテリジェントにルーティングし(小規模タスクには専門的な AI スキルを選択)、開発者は
jobs
webhook_deliveries
などの内部テーブル上の SQL クエリを通じて完全な可視性を維持できます。本プロジェクトは MIT ライセンスで公開されており、アーキテクチャやジョブ契約に関するドキュメントもオープンに提供されています。

  • 欠けている要素(ある場合): なし。
  • 推測/飛躍(ある場合): なし。
  • 改善されたサマリー(必要な場合;なければ元のままを繰り返す): [上記を参照]

本文

エンジニアリングのループを支援する AI チームメイトです。Broccoli は Linear のチケットをレビュー可能な PR に変換し、Claude と Codex を使用して、あなたの Google Cloud プロジェクト上で動作します。

Broccoli を選ぶ理由

  • 🎯 Linear チケット → 審査可能な PR。 イシューを Broccoli ボットに割り当てれば、寝ている間にボットが計画を立て、実装を行い、プルリクエストを作成してくれます。
  • 🔒 あなたのインフラ。あなたのキー。あなたのデータ。 Postgres に対してデプロイされた GCP プロジェクト上で動作します。サードパーティによるコントロールプレーンはなく、テナNCY を脱出してデータを流出することはありません。
  • 🧱 リリース日からプロダクショングレード。 サーブレスな Cloud Run + Secret Manager + ウェブフックの重複防止 + 永続的なジョブ状態管理を採用。これはおもちゃではありません。
  • 🧩 プロンプトはすべてあなたがお持ち。 当社の見解を示すプロンプトテンプレートから始めて、コードと同期してフォークし、調整し、バージョン管理できます。
  • すべての PR に対する AI コードレビュー。 Claude と Codex は差分を読み取り、実行可能なコメントを残し、求められた際は修正コミットをプッシュします。
  • 🛠️ 約 30 分以内でのデプロイ。 ブートストラップスクリプト一つ、設定ファイル一つ、ウェブフック二つでリリース準備完了。

コーディングエージェントと共に使用法

以下のプロンプトを好みのコーディングエージェント(例:codex cli)に貼り付けてください:

このリポジトリを Google Cloud プロジェクトにデプロイしてください。

GitHub リポジトリの URL だけを与えられた場合は、まずリポジトリをクローンしてください。すでにローカルでリポジトリを開いている場合は、既存のチェックアウトから作業を進めてください。

このリポジトリのデプロイ指示書、スクリプト、および`.agents/skills/broccoli-oss-gcp-deploy/SKILL.md` を使用してください。これはコードベースを検証するだけの依頼ではなく、アプリをデプロイするための依頼として処理してください。

前提条件がまだ満たされていないと仮定しないでください。発見フェーズでは、以下のチェックポイントを一つずつ説明し、各項目について私からの回答を確認してから次の項目に進んでください。README の該当セクションが存在する場合は、再説明するのではなくそのページを案内してください。

1. GCP プロジェクトおよび請求権限。Google Cloud プロジェクトがあり、かつbillingが適用された状態で、`gcloud` がそのアカウントにログイン済みかどうか確認してください。もしなければ、https://console.cloud.google.com/cloud-resource-manager でプロジェクトを作成し、https://console.cloud.google.com/billing/projects で billing を適用するための手順を案内するか、デプロイスキルがプロジェクト作成を代行してくれる旨を提示してください。Project ID を記録してください。
2. GitHub App。Broccoli に必要な権限(Contents: リード/ライト、Pull requests: リード/ライト、Issues: リード/ライト、Metadata: リードのみ)を持つ GitHub App を作成済みかどうか確認してください。なければ、`README.md -> デプロイを GCP で実行する -> 1. GitHub App を作成する` のステップごとに案内してください。App ID の数値と、プライベートキープ PEM ファイルをローカルにダウンロードして記録させてください。現時点ではプレースホルダーのホームぺージ/Webフック URL でも構いません;ブートストラップで実際の URL が出力されます。
3. Linear ボットユーザーおよび API キー。**重要:** Linear API キーは、専用の Linear ボットユーザーに属している必要があります。個人のアカウントからのキーを使用すると、「ボットに割り当てられたイシューがトリガーになる」というフローが静かに失敗します。すでに専用のボットユーザーが存在するかどうか確認してください。なければ、`README.md -> 2. Linear ボットユーザーを指定する`: Linear ユーザーを作成または指定し、Broccoli を介して問題がルーターされるすべてのチームに追加し、そのボットユーザーとしてログインする(または管理者がそのユーザーに変更する)ことで、該当ユーザーの設定ページから API キーを生成してください。キーが使用可能であるとして受け入れる前に、それが私の個人のアカウントからのものではなく、ボットユーザーからのものかについて明確に確認してください。ボットユーザー ID を記録してください。
4. OpenAI および Anthropic API キー。各アカウントで請求権限付きのアクティブな API キーが存在するかどうか確認してください。なければ、OpenAI および Anthropic の API キーページに送ってもらい、作成を行ってください。
5. Linear ウェブフック。これは後から行われ、ブートストラップがサービス URL を出力した後で設定されます。現時点では、サービス URL がある場合、`${Service URL}/webhooks/linear` への Linear ウェブフックを追加し、自動生成された `broccoli-oss-linear-webhook-secret` を使用してイシューおよびイシューラベルイベントを購読する必要がある旨をお伝えください。このステップについては現時点では何も行う必要はありません。
6. Secret Manager の population 。ターゲットプロジェクトが存在すれば、オペレーター管理の 4 つのシークレット(`broccoli-oss-github-app-private-key-pem`、`broccoli-oss-linear-api-key`、`broccoli-oss-openai-api-key`、`broccoli-oss-anthropic-api-key`)ごとに、ターゲットプロジェクト向けの正確な Secret Manager コンソール URL を提示し、各シークレットに `latest` バージョンが存在することの確認を受け取るまで一時停止します。ブートストラップ後に自動生成されたウェブフックおよびデータベースパスワードのシークレットはあなたが入手するものなので、それらには触れません。

上記チェックポイント後のワークフロー:
- 変異を伴わない発見フェーズを実行し、`gcloud`認証、請求権限、組織またはプロジェクト権限、または必要なローカルツールなどの欠落で早期に失敗します。
- ターゲット GCP プロジェクトが存在しない場合は、まず作成または準備します。
- クラウド変更を行う前に、解決されたデプロイ計画および不足している非シークレット入力を表示します。
- シークレットをチャットに貼り付けることは決して行いません。必要なシークレットが不足している場合、ターゲットプロジェクトで population する必要があるシークレット名の正確な一覧を示し、存在が確認されるまで一時停止します。
- 推測よりも、リポジトリの既存のスクリプト、文書化されたデフォルト、およびデプロイ後のチェックを優先します。
- デフォルトでは Cloud Build パスをローカルの Docker よりも使用します。
- デプロイ後、安全に実行できる検証手順を継続し、サービス URL、残りの手動セットアップ(チェックポイント 5 の Linear ウェブフックを含む)、およびスモークテストの結果を報告します。

これはエージェントがデプロイを主導する際に最も高速なパスです。代わりに手動のステップバイステップのパスを使用したい場合は、以下のガイドを使用してください。それはプロジェクト作成から始まり、手動セットアップが行われる場所を正確に示しています。

目次


アークテクチャの概要

Broccoli は共有 Postgres 上で動作する 2 つの Cloud Run ワークロードとして稼働します:

コンポーネントロール
broccoli-oss-service
GitHub と Linear のウェブフックを受信し、署名を検証し、配信を重複防止し、ジョブレコードを作成する FastAPI サービス。
broccoli-oss-runner
vendored プロンプトテンプレートに対して codex および claude CLI を使用して自動化を実行する Cloud Run ジョブ。
Postgresジョブ、ウェブフック配信、PR ステート、Linear イシューステート、およびリポジトリ構成の永続的な状態。
Secret ManagerGitHub App プライベートキー、ウェブフックシークレット、LLM API キー、データベース URL を保持します。

詳細な設計については ARCHITECTURE.md を参照し、ウェブフックおよび状態モデルの契約については JOB-CONTRACT.md を参照してください。


前提条件

  • 新しいプロジェクトを作成して billing を適用するか、既存のプロジェクトを管理できる Google Cloud アカウントが必要です。
  • その Google Cloud アカウントに認証された
    gcloud
    です。最終的なプロジェクト ID を事前に知る必要はありません。
  • GitHub、Linear、および GCP コンソールへのブラウザアクセスが必要です。いくつかの最初のセットアップ手順は意図的に手動で行う必要がありますが、これに必要な値はこれらの製品内にあり、チャットに貼り付けるべきではありません。
  • ローカルでの Docker の使用を意図する場合のみ
    buildx
    付きの Docker が必要です(デフォルトの Cloud Build パスの代わりに画像をローカルでビルドしたい場合)。
  • オペレーターツール(マイグレーション、シード、プリフライト)のために Python 3.12+ および uv が必要です。
  • Anthropic API キーおよび OpenAI(または Codex)API キー、またはそれらの作成能力が必要です。

GCP でのデプロイ方法

以下の手順は初回のオペレーター向けに書かれています。ゼロから始まり、値の源泉を説明し、セキュリティ上の理由から手動で行う必要があるステップを指摘します。

0. GCP プロジェクトの作成または選択

Broccoli シークレットを追加するか Cloud Run サービスをデプロイするには、Google Cloud プロジェクトが必要です。

すでに使用するプロジェクトがある場合:

  1. GCP コンソールでプロジェクトを開きます。
  2. プロジェクト ID を記録してください。これ以降の手順で使用されます。
  3. そのプロジェクトに billing が適用されていることを確認します。

まだプロジェクトがない場合:

  1. Google Cloud の「リソース管理」ページを開きます:https://console.cloud.google.com/cloud-resource-manager
  2. プロジェクトを作成するか、
    broccoli-oss-gcp-deploy
    スキルを使用してプロジェクトを作成してもらいます。
  3. billing プロジェクトページで billing を適用します:https://console.cloud.google.com/billing/projects
  4. 新しいプロジェクト ID を記録してください。

注記:Codex デプロイスキルを使用する場合、そのスキルはプロジェクトの作成、billing の適用、必要な API の有効化、および Secret Manager シークレットコンテナの作成を代行できます。これは初回オペレーターにとって最も簡単なパスであり、シークレットを追加する前に実際のプロジェクトをクリックできるためです。

1. GitHub App を作成する

GitHub App(PAT ではありません)を使用することで、Broccoli がスコープ付きインストールトークンを発行できます。

リポジトリ権限:

  • Contents: リード/ライト
  • Pull requests: リード/ライト
  • Issues: リード/ライト
  • Metadata: リードのみ

イベントの購読: プルリクエストレビュー。

現時点では、ホームぺージ URL および Webフック URL をプレースホルダーに設定してください。実際のサービス URL が出力されるステップ 6 で更新します。

App ID とプライベートキープ PEM をダウンロードして記録してください。

  • GitHub App ID: GitHub アプリに割り当てられた数値識別子です。
    deploy/bootstrap.sh
    はこれをサービスおよびランナーに渡し、インストールトークンを発行するために使用します。
  • GitHub App プライベートキー PEM: GitHub アプリ設定ページで生成するプライベートキーファイルです。Broccoli はこれを App ID と組み合わせて、アプリとして GitHub に認証するために使用します。PEM ファイルはローカルに保持してください。チャットには貼り付けてくださいません。

2. Linear ボットユーザーを指定する

イシューが特定の Linear ユーザーに割り当てられた際に Broccoli がトリガーされます。

  1. Broccoli ボットとして機能する専用の Linear ユーザーを作成または指定します。
  2. そのユーザーには、Broccoli を介してルーターされるすべてのチームへのアクセス権を与えます。
  3. 読み込み、コメント、ラベルを読み取るために、そのチーム用にスコープされた Linear API キーを生成します(トークンでも可)。
  4. ボットユーザー ID を記録してください。ステップ 8 でグローバル構成にシードされます。

3. 適切なプロジェクトで Secret Manager を開く

GCP を初めて使用する場合、これは通常混乱を引き起こすステップです:シークレットはあなたのデプロイプロジェクト内の Google Cloud Secret Manager に格納されます。

  1. Secret Manager を開きます:https://console.cloud.google.com/security/secret-manager
  2. ページの上部にあるプロジェクトセレクターを使用して、Broccoli デプロイプロジェクトに変更します。
  3. 選択されたプロジェクト ID がステップ 0 で記録したものと同じであることを確認します。

注記:Codex デプロイスキルでプロジェクトを準備した場合、一部またはすべてのシークレットコンテナが既に存在する可能性があります。これは問題ありません。既存のシークレットを開き、「新しいバージョンを追加」をクリックすればよいでしょう。

4. 必要なシークレット値を入力する

これらの値を手動で入力する必要があります。これらは GitHub、Linear、OpenAI、および Anthropic アカウントからきており、デプロイヘルパーがあなたの代わりに安全に読み取ることはできないからです。シークレット値をチャットに貼り付けてくださいません。GCP コンソールまたは独自のターミナルを通じて Secret Manager に追加してください。

以下の各シークレットについて:

  1. Secret Manager で「シークレットを作成」をクリックするか、同じ名前の既存のシークレットを開きます。
  2. 正確なシークレット名を使用します。
  3. 値を貼り付けるか、ファイルの内容をアップロードします。
  4. 保存し、シークレットに
    latest
    バージョンが存在することを確認します。

ブートストラップ前の必要事項:

シークレット値の元対応策
broccoli-oss-github-app-private-key-pem
ステップ 1 で GitHub アプリ設定からダウンロードした PEM ファイル完全な PEM 内容をシークレット値として貼り付ける
broccoli-oss-linear-api-key
ステップ 2 の Linear ボットユーザー用の Linear API キーAPI キーをシークレット値として貼り付ける
broccoli-oss-openai-api-key
OpenAI API キーページAPI キーをシークレット値として貼り付ける
broccoli-oss-anthropic-api-key
Anthropic API キーページAPI キーをシークレット値として貼り付ける

この README の生シェルパスに従っている場合、手動で作成するオプション:

シークレット使用目的取得または生成方法
broccoli-oss-db-password
broccoli_oss PostgreSQL ユーザーのパスワード;Cloud SQL デプロイ用の broccoli-oss-database-url を導出するためローカルでランダムな値を生成、例:
openssl rand -hex 32
broccoli-oss-gh-webhook-secret
GitHub が Broccoli へのウェブフックリクエストに署名するために使用する共有シークレットローカルでランダムな値を生成、例:
openssl rand -hex 32
、後に GitHub アプリのウェブフックシークレットフィールドに貼り付ける
broccoli-oss-linear-webhook-secret
Linear が Broccoli へのウェブフックリクエストに署名するために使用する共有シークレットローカルでランダムな値を生成、例:
openssl rand -hex 32
、後に Linear ウェブフック設定に貼り付ける

注記:broccoli-oss-gcp-deploy ヘルパーを使用している場合、プロジェクトが存在した後、

broccoli-oss-db-password
broccoli-oss-gh-webhook-secret
、および
broccoli-oss-linear-webhook-secret
を自動生成できます。それでも、上記の 4 つのオペレーター管理シークレットはあなたが提供する必要があります。

デフォルトの Cloud SQL パスの場合:

  • broccoli-oss-database-url
    を事前にpopulation する必要はありません。
    deploy/bootstrap.sh
    はそれらを導出し、そのシークレットを代わりに書き込みます。
  • broccoli-oss-db-password
    は必要です。Cloud SQL データベースユーザーのパスワードであり、ランダムで高エントリの文字列であるべきです。

**ローカル開発またはカスタムデプロイの場合:**ランナーは

OPENAI_API_KEY
の代わりに
CODEX_API_KEY
を受け付けます。

5. Cloud Build で画像をビルドしてプッシュする

cd path/to/this-repo
export GCP_PROJECT_ID=your-project
export GCP_REGION=us-central1
export TAG=v0.1.0
export PUSH=1
./deploy/build-and-push.sh

デフォルトでは、

deploy/build-and-push.sh
は Google Cloud Build を使用します。つまり、Google が GCP プロジェクト内で画像をビルドおよびプッシュするため、推奨されるデプロイパスにはローカル Docker は必要ありません。スクリプトは
SERVICE_IMAGE=...
および
RUNNER_IMAGE=...
を出力するため、次のステップにコピーできます。

ローカルで Docker を使用して意図的に画像をビルドしたい場合は、以下のようになります:

export BUILD_BACKEND=docker
./deploy/build-and-push.sh

6. ブートストラップを実行する

deploy/bootstrap.sh
は冪等であり、増分的な Cloud Run env/secret アップデートを使用するため、安全に再実行できます。

export GCP_PROJECT_ID=your-project
export GCP_REGION=us-central1
export GITHUB_APP_ID=123456
export SERVICE_IMAGE=us-docker.pkg.dev/your-project/containers/broccoli-oss-service:v0.1.0
export RUNNER_IMAGE=us-docker.pkg.dev/your-project/containers/broccoli-oss-runner:v0.1.0

# 一般的なオプションオーバーライド:
export INGRESS_SERVICE_NAME=broccoli-oss-service
export RUNNER_JOB_BASENAME=broccoli-oss-runner
export RUNNER_TIMEOUT_SECONDS=3600
export DB_BACKEND=cloudsql
export DB_INSTANCE_NAME=broccoli-oss-pg
export DB_AUTHORIZED_NETWORKS=0.0.0.0/0

./deploy/bootstrap.sh

ブートストラップは以下のものを出力します:

  • デプロイされたサービス URL
  • GitHub ウェブフック URL (
    ${Service URL}/webhooks/github
    )
  • Linear ウェブフック URL (
    ${Service URL}/webhooks/linear
    )
  • Cloud Run サービスおよびジョブリソース名

DB_BACKEND=cloudsql
の場合、ブートストラップはさらに Public IPv4 ありで Cloud SQL インスタンスをパッチ適用し、
DB_AUTHORIZED_NETWORKS
から
authorizedNetworks
を設定します。デフォルトは
0.0.0.0/0
で、どこからの接続も許可されます。直接的な Postgres アクセスを制限したい場合は、より狭い CIDR リストでオーバーライドしてください。

GitHub アプリ設定に戻り、ホームぺージ URL および Webフック URL を上記の値に変更し、次に

broccoli-oss-gh-webhook-secret
の値をアプリのウェブフックシークレットフィールドに貼り付けてください。

7. リポジトリに GitHub App をインストールする

GitHub アプリ設定から:

  1. 「Install App」をクリックします。
  2. ターゲットリポジトリが所有するアカウントまたは組織を選択します。
  3. 意図的に広範囲のスコープを持つ場合を除き、「Only select repositories」を選択します。
  4. ターゲットリポジトリへのアクセス権を与えます。
  5. インストール URL (
    /settings/installations/<id>
    ) からインストール ID をキャプチャします(次のステップで使用されます)。

8. マイグレーションを実行してリポジトリ構成をシードする

デフォルトの Cloud Run + Cloud SQL デプロイでは、

broccoli-oss-database-url
は Cloud Run ランタイム向けに書き込まれ、
/cloudsql/...
Unix ソケットパスを使用します。これはデプロイされたサービスおよびランナーには正しい値ですが、ラップトップから直接使用する価値のある値ではありません。

ローカルオペレーターコマンドの場合は、Cloud SQL Auth Proxy でローカル TCP チュNEL を開始し、

broccoli-oss-db-password
から ローカル DATABASE_URL を構築して実行してください:

cloud-sql-proxy your-project:us-central1:broccoli-oss-pg --port 5432
DB_PASSWORD="$(gcloud secrets versions access latest \
  --secret=broccoli-oss-db-password \
  --project your-project)"
export DATABASE_URL="postgresql://broccoli_oss:${DB_PASSWORD}@127.0.0.1:5432/broccoli_oss"

uv sync --dev
uv run python -m app.operator migrate
uv run python -m app.operator schema-version

ブートストラップ後の Codex デプロイスキルを使用している場合は、生成されたシークレットを Secret Manager から取得し、可能な限り既存のターゲットプロジェクト資格証明を使用する代わりにこれらのヘルパーコマンドを実行するよう指示される必要があります。以下のコマンドは手動フォールバックパスです。

GCP でのオペレーターフローをラップトップからの代わりに Codex で完了させたい場合は、次のようになります:

python .agents/skills/broccoli-oss-gcp-deploy/scripts/deploy.py \
  --github-app-id <github-app-id> \
  --project-id your-project \
  --apply \
  --post-deploy-operator \
  --github-repo-full-name acme/demo \
  [--git-clone-url https://github.com/acme/demo.git] \
  [--default-branch main] \
  [--github-installation-id 12345678] \
  [--linear-team-id <linear-team-id>] \
  [--linear-bot-user-id <linear-bot-user-id>]

このパスでは、一時的な Cloud Run ジョブを作成してオペレーターコマンドを実行し、完了するとその一時ジョブを削除することで、GCP 内で migrate、schema-version、seed、および preflight を実行します。ラッパーがターゲットプロジェクトの独自のシークレットおよび API から安全に発見できる場合、任意のオプションリポジトリまたは Linear フラグは省略できます。

Linear ボットユーザー ID および候補チーム ID は、ターゲットプロジェクトの既存の Linear API キーを使用して発見できます:

LINEAR_API_KEY="$(gcloud secrets versions access latest \
  --secret=broccoli-oss-linear-api-key \
  --project your-project)"

curl -s https://api.linear.app/graphql \
  -H "Authorization: ${LINEAR_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{"query":"query ViewerAndTeams { viewer { id name } teams { nodes { id key name } } }"}'

レスポンスには以下が含まれます:

  • viewer.id
    : API キーがボットユーザーに属している場合、通常はボットユーザー ID です
  • teams.nodes[].id
    : 候補となる
    linear_team_id

リアルな値で

db/seed/example.seed.yaml
(またはコピー)を編集します:

repos:
  - repo_key: demo
    enabled: true
    github_repo_full_name: acme/demo
    github_installation_id: 12345678   # ステップ 7 のインストール URL /settings/installations/<id> から
    git_clone_url: https://github.com/acme/demo.git
    default_branch: main
    base_branch: main
    linear_team_id: <linear-team-uuid>
    config_json: {}

global:
  linear_bot_user_id:
    userId: <linear-bot-user-id>       # ステップ 2 から

今日サポートされているトップレベルキー:

repos
および
global
linear_bot_user_id
を含む)。シードは重複する repo_key、重複する github_repo_full_name、空の必要な文字列、および未知のキーを拒否します。

uv run python -m app.operator seed --file db/seed/example.seed.yaml

9. ウェブフックを登録する

GitHub または Linear に貼り付ける必要がある場合は、生成されたウェブフックシークレットを自分で取得してください:

gcloud secrets versions access latest \
  --secret=broccoli-oss-gh-webhook-secret \
  --project your-project

gcloud secrets versions access latest \
  --secret=broccoli-oss-linear-webhook-secret \
  --project your-project
  • GitHub: GitHub アプリのウェブフックはステップ 6 で既に構成されています;単に
    ${Service URL}/webhooks/github
    を指していることを確認し、ウェブフックシークレットが
    broccoli-oss-gh-webhook-secret
    と一致することを確認します。
  • Linear:
    ${Service URL}/webhooks/linear
    に指針する新しいウェブフックを追加し、
    broccoli-oss-linear-webhook-secret
    の値を使用します。イシューおよびイシューラベルイベントへの購読を行います。このステップは手動で意図的に行われるか、Codex が管理者機能付きの Linear 資格証明を与えることを選択する場合を除き;通常のボット API キーは非管理者と想定されます。

ルーティングルール:

  1. イシューは構成されたボットユーザーに割り当てられている必要があります。
  2. 正確に一つのルーティングラベルが有効な repo_key に一致する必要があります。
  3. 0 < estimate < 3
    は小さな見積もりスキルパスを選択します;それ以外の場合はデフォルトパスを使用します。

10. プリフライトを実行する

プリフライトは DB コネクティビティ、Secret Manager 存在、Cloud Run ジョブメタデータ、最初の有効なリポジトリへの GitHub アプリインストールトークン発行、Linear API アクセス、および vendored プロンプトテンプレート完全性の検証を行います。

export GITHUB_APP_ID=123456
export GITHUB_APP_PRIVATE_KEY_PEM="$(gcloud secrets versions access latest \
  --secret=broccoli-oss-github-app-private-key-pem \
  --project your-project)"
export GH_WEBHOOK_SECRET="$(gcloud secrets versions access latest \
  --secret=broccoli-oss-gh-webhook-secret \
  --project your-project)"
export LINEAR_API_KEY="$(gcloud secrets versions access latest \
  --secret=broccoli-oss-linear-api-key \
  --project your-project)"
export LINEAR_WEBHOOK_SECRET="$(gcloud secrets versions access latest \
  --secret=broccoli-oss-linear-webhook-secret \
  --project your-project)"
export RUNNER_JOB_NAME="projects/your-project/locations/us-central1/jobs/broccoli-oss-runner"
export GCP_PROJECT_ID=your-project
export GCP_REGION=us-central1
export APP_BASE_URL=https://your-service-url

uv run python -m app.operator preflight

11. スモークテストを実行する

GitHub ウェブフックカナリ:

APP_BASE_URL=https://your-service-url \
DATABASE_URL=postgresql://... \
GH_WEBHOOK_SECRET=... \
CANARY_GITHUB_REPO_FULL_NAME=acme/demo \
CANARY_GITHUB_PR_NUMBER=12 \
uv run python tests/smoke/github_webhook_canary.py

Linear ウェブフックカナリ:

APP_BASE_URL=https://your-service-url \
DATABASE_URL=postgresql://... \
LINEAR_WEBHOOK_SECRET=... \
CANARY_LINEAR_ISSUE_ID=issue-id \
CANARY_LINEAR_BOT_USER_ID=bot-user-id \
CANARY_LINEAR_CREATOR_ID=creator-id \
CANARY_LINEAR_REPO_KEY=demo \
uv run python tests/smoke/linear_webhook_canary.py

両スクリプトは HTTP レスポンズに加えてマッチングする webhook_deliveries 行を出力します。これで稼働しています。


Broccoli の操作

ジョブ状態の確認

便利なテーブル:

webhook_deliveries
jobs
github_pr_state
linear_issue_state
repo_configs
global_config

SELECT provider, delivery_id, processed_at, ignored_reason, error_stage, job_id
FROM webhook_deliveries
ORDER BY received_at DESC
LIMIT 20;

SELECT id, kind, status, routing_repo_key, error_kind, error_message
FROM jobs
ORDER BY created_at DESC
LIMIT 20;

-- ライフサイクルコメントおよび起動メタデータ(尽力)
SELECT
  id,
  kind,
  run_metadata->'launch' AS launch,
  run_metadata->'linear'->'commentIds' AS linear_comment_ids,
  run_metadata->'githubReviewFeedback' AS github_review_feedback,
  run_metadata->'run' AS run_stage
FROM jobs
ORDER BY created_at DESC
LIMIT 20;

ライフサイクルコメントは尽力による側面効果です。GitHub/Linear API が利用不可または権限が不足している場合でも、

jobs
は実行されるべきであり、
run_metadata
は何が投稿できたかを記録します。

無視されたウェブフックレスポンス

すべての配信(無視されたものを含む)が記録されるため、ルーティング決定は監査可能です。一般的な

ignored_reason
値:

理由意味
unsupported_eventイベントは Broccoli がサポートする表面外にあります
duplicate_delivery配信 ID はすでに永続的に処理されました
missing_repo_routingウェブフックペイロードに一致する有効な repo_key がない
review_state_not_changes_requestedGitHub リビューは実行可能なアクションではありません
not_automation_readyLinear イシューは現在、構成されたボットユーザーには割り当てられていません

セーフな失敗したウェブフックの再試行

ウェブフック配信重複防止は Postgres に保存されています。安全な振る舞い:

  • オリジナルの配信が既に処理された場合、再配信は
    duplicate_delivery
    を返します。
  • オリジナルのジョブレコードが存在するが起動の帳簿作成が失敗した場合、再配信は保存されたジョブ ID を再利用します。
    jobs
    または
    webhook_deliveries
    行を手動で変更しないでください。意図的に状態を修復する場合を除きます。

推奨される再試行パス:

  1. 根本原因を修正します。
  2. GitHub または Linear から元のウェブフックを再配信します。
  3. 同じ配信 ID が終端のジョブステートに到達することを確認します。

IAM

Broccoli は「厳格な最小権限モデル」よりも「最初のデプロイで動作する」方を好みます。稼働後に緊密化してください。

ランタイムサービスアカウント:

  • ングレスサービスアカウント:
    project-level roles/run.developer
  • ングレスおよびランナーサービスアカウント:
    roles/secretmanager.secretAccessor
  • ングレスおよびランナーサービスアカウント:
    roles/cloudsql.client
    (Cloud SQL を使用する場合のみ)

デプロイヤー権限: プロジェクトオーナーまたはエディター、およびサービスアカウントの作成と IAM バインディングを作成する権限。

IAM 決定のために参照されたドキュメント:

  • Cloud Run: ジョブの作成
  • Cloud Run: ジョブの実行
  • Cloud Run IAM ロールおよび権限

ローカル開発

uv sync --dev
cp .env.example .env   # リアルな値を入力;.env をコミットしないでください
uv run ruff check .
uv run pytest

.env
ファイルは gitignored です。完全なコントリビューターワークフローについては CONTRIBUTING.md を参照してください。


ドキュメンテーション

ライフサイクルコメントパリティ注記:

  • Linear イシュー自動化は尽力によるライフサイクルコメント(キューイング、開始、prOpened、終端)を投稿します。
  • GitHub リビューフィードバックジョブは尽力による「ラウンサーが開始された」コメントおよび終端の失敗コメントを投稿します。
  • その他のプライベートリポジトリ行動(デバッグモード、plan-verbatim モード、追加修復フロー)は意図的に範囲外です。

コントリビューション

イシューとプルリクエストをお待ちしています。設定、期待値、およびレビューループについては CONTRIBUTING.md から始めます。公的なイシューにシークレット、認証情報、または他の機密デプロイ詳細を投稿しないでください。


ライセンス

Broccoli OSS は MIT ライセンスの下でリリースされています。バンドルサードパーティの通知については NOTICE を参照してください。


FAQ

  • 外部管理された Postgres を使用できますか? はい —
    DB_BACKEND
    cloudsql
    以外の何かに設定し、
    DATABASE_URL
    をインスタントに指してください。
  • LLM を交換できますか? ランナーは codex および claude CLI にシェルアウトします;交換にはランナーハンドラーおよび vendored プロンプトテンプレートのフォークが必要です。これをプラグ可能にするコントリビューションをお待ちしています。
  • ホスト版がありますか? 今回はありません。Broccoli はあなたの GCP プロジェクトで、あなたのキーに対して動作します。
  • クローズドソース版がありますか? 他のインフラストラクチャ上で動作する Broccoli のクローズドソース版が存在しますが、ここでは公開されていません。このリポジトリの OSS パスは自己完結しており、プロダクション準備ができています。

同じ日のほかのニュース

一覧に戻る →

2026/04/23 5:27

Apple、警察による iPhone の消去されたチャットメッセージの抽出を可能にしていたバグの修正を提供。

## Japanese 翻訳: Apple は緊急に重要なソフトウェア更新をリリースし、iOS 18 およびそれ以前のバージョンを実行する iPhone と iPad(すべてを含む)で、Signal や WhatsApp のような暗号化アプリから削除されたメッセージを法執行機関のフォレンジックツールが抽出できるという深刻なセキュリティ欠陥を修正しました。この脆弱性は、ユーザーがメッセージを削除してもデバイス上で最大 1 ヶ月間キャッシュとして保持され、削除されない通知データが原因でした。これにより、「セットして忘れましょう」という設計思想を持つ危険人物向け自動削除タイマーにもかかわらず、法執行機関(FBI を含む)は押収されたデバイス上の私的チャットを再構築することができました。この問題は Signal 社長メレディス・ホイッターによって確認され、当初は404 Mediaによって開示されました。問題の核心は、削除対象としてマークされた通知が予期せずにデバイス上に保持されたことです。OS 全体のアップグレードを必要とせず、即時のリスクを軽減するために、Apple は該当デバイスに修正をバックポートし、不可欠なプライバシー保護を回復するとともに、将来的なフォレンジック攻撃を防ぐためにモバイルセキュリティプロトコルにおけるより厳格なデータキャッシュ管理の必要性を強調しました。

2026/04/23 2:35

私たちが発見したのは、あなたのすべてのプライベートな Tor アカウントを相互に結びつける安定した Firefox の識別子です。

## 日本語訳: 元のサマリーは優れている—it は簡潔で明瞭であり、主要ポイントリストからのすべての主要ポイントを余計な冗談抜きに捉えている。 ## サマリー: Firefox ベースのブラウザには、プライバシー上重大な欠陥があり、ウェブサイトがプライベートモードであってもユーザーを一意に追跡できるようになっています。この問題は、`IndexedDB`(ブラウザの保存システム)がデータをどのように順序付けるかという仕組みから生じており、これは永続的な「指紋」を作り出します。この順序付けはブラウザを完全に再起動するまで安定するため、異なるウェブサイトにおいて同様のパターンを観測し、従来のクッキーを使用せずにユーザーのウェブサイトの活動同士をつなげることを可能とします。この脆弱性は、セッションデータを閉じた後で消えるかリセットすると期待して匿名性を維持するためにユーザーが依存している Tor の「新しいアイデンティティ」機能のようなプライバシー保護措置を効果的に回避します。 この欠陥がすべての Firefox 派生版で共有される `Gecko` エンジンに存在することに気づいた Mozilla は、最近のバージョン向けの緊急修正をリリースしました。解決策はデータベースリストの表示方法を標準化し、追跡を可能とした内部の保存パターンを取り除きます。その結果、ユーザーはこれらの指紋を完全にクリアするためにブラウザを再起動する必要があります。それまでの間、プライベートブラウジングモードの信頼性が損なわれ、無関係なウェブサイトがユーザーの一貫したクロスサイト行動を識別できないという根本的な信頼が破られます。

2026/04/20 0:19

微小画面向けの 5 ピクセル×5 ピクセルのフォント。

## Japanese Translation: 最も重要な示唆は、AVR128DA28 などのリソース制約の厳しい 8 ビットマイクロコントローラ向けに最適化された、非常に効率的で手作業によるフォント設計にあります。lcamtuf の `5x6 font-inline.h` に基づき、ZX Spectrum のスタイルに触発されたこのアプローチは、ベクトルフォント(メガバイト規模のデータを必要とするため)が失敗したり、限られた RAM を備えたデバイス上で文字列長の計算時に整数溢れ問題を引き起こしたりする記憶制約を解決します。このフォントは合計 350 バイトで完結しており、標準的な 128x64 OLED などコンパクトなディスプレイに適合します。主要な設計判断はグリッド寸法に集中しており、5x5 グリッドが "E" や"M"や"W"のような個別の文字を損なうことなく完全な可読性を維持するための最小サイズであることが特定されました。一方、より小さなグリッドではフォント数の大幅な減少と可読性の低下を引き起こし(例:3x5 に落とすと特定の形状が失われ、3x3 未満では文字セットが単純なコードに縮小されます)。この定幅形式はプログラミングを簡素化し、画面内の文字列長が予測可能(文字数の 6 倍)になります。これにより、厳格にストレージ制限を受けたハードウェア上でもファームウェアは軽量かつ信頼性が保たれます。プロジェクトのソースには、2026 年 4 月に開発された `mcufont.h` および`test.c` と関連するピクセルアートフォントリポジトリが含まれています。

【Show HN】ブルコリ:クラウド上で動作するワンショットコーディングエージェント | そっか~ニュース