Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions .github/workflows/review-swarm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
name: Review swarm

on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]

permissions:
contents: read
pull-requests: write

concurrency:
group: review-swarm-${{ github.event.pull_request.number }}
cancel-in-progress: true

jobs:
review:
runs-on: ubuntu-latest
# Ordering invariant: swarm 60m < poll 65m < job 75m.
timeout-minutes: 75
steps:
- name: Check out PR head
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
path: pr-head
fetch-depth: 0

- name: Check out immutable gate from main
uses: actions/checkout@v4
with:
ref: main
path: gate-files
sparse-checkout: |
workflows/review-swarm.yaml
.github/workflows/scripts/swarm-post.sh
.github/workflows/scripts/swarm-prepare.sh
.github/workflows/scripts/swarm-verdict.sh

- name: Validate cloud authentication
env:
RELAY_WORKSPACE_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
run: |
if [ -z "$RELAY_WORKSPACE_KEY" ]; then
echo "RELAY_WORKSPACE_KEY secret not configured; see README § Cloud review swarm." >&2
exit 1
fi

- name: Prepare review input on GitHub runner
env:
GH_TOKEN: ${{ github.token }}
working-directory: pr-head
run: |
../gate-files/.github/workflows/scripts/swarm-prepare.sh \
"${{ github.event.pull_request.number }}"
cp ../gate-files/.github/workflows/scripts/swarm-verdict.sh \
.github/workflows/scripts/swarm-verdict.sh
git add -f .github/workflows/scripts/swarm-verdict.sh

- name: Launch cloud swarm
id: launch
env:
RELAY_API_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
working-directory: pr-head
run: |
response=$(agent-relay cloud run \
../gate-files/workflows/review-swarm.yaml --sync-code --json)
run_id=$(jq -er '.runId // .id' <<<"$response")
echo "run_id=$run_id" >> "$GITHUB_OUTPUT"

- name: Wait for cloud swarm
id: wait
if: always() && steps.launch.outputs.run_id != ''
env:
RELAY_API_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
run: |
# Ordering invariant: swarm 60m < this poll deadline 65m < job 75m.
deadline=$((SECONDS + 3900))
status=timed_out
while [ "$SECONDS" -lt "$deadline" ]; do
response=$(agent-relay cloud status "${{ steps.launch.outputs.run_id }}" --json) || {
status=status_error
break
}
status=$(jq -r '.status // "unknown"' <<<"$response")
case "$status" in
completed|failed|cancelled) break ;;
esac
sleep 15
done
echo "swarm_status=$status" >> "$GITHUB_OUTPUT"
exit 0

- name: Post verdict and transcripts
if: always() && steps.launch.outputs.run_id != ''
env:
GH_TOKEN: ${{ github.token }}
RELAY_API_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
working-directory: pr-head
run: ../gate-files/.github/workflows/scripts/swarm-post.sh "${{ steps.launch.outputs.run_id }}" "${{ github.event.pull_request.number }}"

- name: Enforce swarm result
if: always() && steps.wait.outputs.swarm_status != 'completed'
run: |
echo "Review swarm did not complete successfully: ${{ steps.wait.outputs.swarm_status }}" >&2
exit 1
53 changes: 53 additions & 0 deletions .github/workflows/scripts/swarm-post.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail

run_id=${1:?usage: swarm-post.sh RUN_ID PR_NUMBER}
pr=${2:?usage: swarm-post.sh RUN_ID PR_NUMBER}
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
# shellcheck source=swarm-verdict.sh
source "$script_dir/swarm-verdict.sh"

freshness_marker=$(mktemp)
trap 'rm -f "$freshness_marker"' EXIT
agent-relay cloud sync "$run_id" --dir .

upsert_comment() {
local anchor=$1 body=$2 comment_id
comment_id=$(gh api --paginate "repos/{owner}/{repo}/issues/$pr/comments" \
--jq ".[] | select(.body | contains(\"$anchor\")) | .id" | head -n 1)
if [ -n "$comment_id" ]; then
gh api --method PATCH "repos/{owner}/{repo}/issues/comments/$comment_id" -f body="$body" >/dev/null
else
gh pr comment "$pr" --body "$body" >/dev/null
fi
}

overall=PASSED
summary=''
for lens in maintainability history structure; do
IFS=$'\t' read -r verdict transcript < <(
swarm_lens_result ops/reviews "$pr" "$lens" "$freshness_marker"
)
[ "$verdict" = PASSED ] || overall=FAILED
summary+="- ${lens}: ${verdict}"$'\n'
if [ -n "$transcript" ] && [ -f "$transcript" ]; then
body="<!-- swarm-lens: $lens -->
## Review swarm: $lens

$(cat "$transcript")"
else
body="<!-- swarm-lens: $lens -->
## Review swarm: $lens

No fresh transcript was produced for run \`$run_id\` ($verdict)."
fi
upsert_comment "<!-- swarm-lens: $lens -->" "$body"
done

upsert_comment '<!-- review-swarm -->' "<!-- review-swarm -->
## Review swarm: $overall

$summary
Cloud run: \`$run_id\`"

[ "$overall" = PASSED ]
13 changes: 13 additions & 0 deletions .github/workflows/scripts/swarm-prepare.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail

pr=${1:?usage: swarm-prepare.sh PR_NUMBER}
[[ $pr =~ ^[0-9]+$ ]] || { echo "invalid PR number: $pr" >&2; exit 2; }

mkdir -p .review-target
printf '%s\n' "$pr" > .review-target/pr-number
gh pr diff "$pr" > .review-target/pr.diff
gh pr view "$pr" --json headRefName,headRefOid,title,url > .review-target/pr.json
touch .review-target/run-start
git add -f .review-target/pr-number .review-target/pr.diff \
.review-target/pr.json .review-target/run-start
32 changes: 32 additions & 0 deletions .github/workflows/scripts/swarm-verdict.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env bash

# Shared, fail-closed review transcript selection and verdict extraction.
swarm_latest_transcript() {
local reviews_dir=$1 pr=$2 lens=$3
find "$reviews_dir" -maxdepth 1 -type f \
-name "????????-????-pr${pr}-${lens}.md" -print 2>/dev/null |
LC_ALL=C sort | tail -n 1
}

swarm_transcript_verdict() {
local transcript=$1 token
token=$(awk 'NF { last=$NF } END { print last }' "$transcript")
case "$token" in
REVIEW_PASSED) printf '%s\n' PASSED ;;
REVIEW_FAILED) printf '%s\n' FAILED ;;
*) printf '%s\n' UNCLEAR ;;
esac
}

swarm_lens_result() {
local reviews_dir=$1 pr=$2 lens=$3 freshness_marker=${4:-}
local transcript
transcript=$(swarm_latest_transcript "$reviews_dir" "$pr" "$lens")
if [ -z "$transcript" ]; then
printf 'MISSING\t\n'
elif [ -n "$freshness_marker" ] && [ ! "$transcript" -nt "$freshness_marker" ]; then
printf 'STALE\t%s\n' "$transcript"
else
printf '%s\t%s\n' "$(swarm_transcript_verdict "$transcript")" "$transcript"
fi
}
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ dist/
.env
.agentworkforce/
.cargo-home/
.review-target

# Toolchains materialize inside the workspace in a cloud sandbox and must never
# be committed or delivered. Run f18ec684's patch carried .rustup-home/ files;
# ops/deliver-run.sh scrubs them too, but ignoring them is the durable fix.
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ Nine gates, in `docs/RFC-0001` §3. Gate 1 first: a relayflow can run — the he
ladder survives `kill -9` at every boundary.

Private while we build. YC 2026-09-15 runs on this base.

## Cloud review swarm

Every pull request launches the cloud review swarm. Repository administrators
must configure an Actions secret named `RELAY_WORKSPACE_KEY` with a workspace
key obtained using `agent-relay workspace key --reveal-secrets`. The workflow
fails during preflight, before submitting a run, when the secret is absent.
Loading
Loading