Skip to content
Closed
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
104 changes: 104 additions & 0 deletions .github/workflows/review-swarm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
name: Review swarm

on:
pull_request:
types: [opened, reopened, synchronize, 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: job 75m > poll deadline 65m > swarm timeout 60m.
timeout-minutes: 75
steps:
- name: Check out immutable gate from main
uses: actions/checkout@v4
with:
ref: main
path: gate

- name: Check out reviewed PR head
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
path: target

- 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 §Review swarm cloud authentication" >&2
exit 1
fi

- name: Install Agent Relay
run: npm install --global agent-relay@11.8.7

- name: Prepare immutable gate and PR evidence
env:
GH_TOKEN: ${{ github.token }}
run: gate/.github/workflows/scripts/swarm-prepare.sh gate target "${{ github.event.pull_request.number }}"

- name: Launch cloud swarm
id: launch
working-directory: target
env:
RELAY_WORKSPACE_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
run: |
response=$(agent-relay cloud run .review-gate/review-swarm.yaml --sync-code --json)
run_id=$(jq -r '.runId // .run_id // .id // empty' <<<"$response")
if [ -z "$run_id" ]; then
echo "LAUNCH_FAILED: cloud response did not contain a run id" >&2
echo "$response" >&2
exit 1
fi
echo "run_id=$run_id" >> "$GITHUB_OUTPUT"

- name: Wait for terminal cloud status
id: wait
env:
RELAY_WORKSPACE_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
run: |
# Ordering invariant: poll deadline 3900s > swarm timeout 3600s.
deadline=$((SECONDS + 3900))
swarm_status=timed_out
while (( SECONDS < deadline )); do
status_json=$(agent-relay cloud status "${{ steps.launch.outputs.run_id }}" --json 2>/dev/null || true)
status=$(jq -r '.status // empty' <<<"$status_json")
case "$status" in
completed|failed|cancelled)
swarm_status=$status
break
;;
esac
sleep 15
done
echo "swarm_status=$swarm_status" >> "$GITHUB_OUTPUT"
exit 0

- name: Sync evidence and update PR comments
id: post
if: always() && steps.launch.outputs.run_id != ''
env:
GH_TOKEN: ${{ github.token }}
RELAY_WORKSPACE_KEY: ${{ secrets.RELAY_WORKSPACE_KEY }}
run: |
sync_started=$(date +%s)
gate/.github/workflows/scripts/swarm-post.sh \
target "${{ github.event.pull_request.number }}" \
"${{ steps.launch.outputs.run_id }}" \
"${{ steps.wait.outputs.swarm_status }}" "$sync_started"

- name: Enforce swarm result
if: always()
run: |
[ "${{ steps.wait.outputs.swarm_status }}" = completed ] || exit 1
[ "${{ steps.post.outputs.overall }}" = REVIEW_PASSED ] || exit 1
61 changes: 61 additions & 0 deletions .github/workflows/scripts/swarm-post.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#!/usr/bin/env bash
set -euo pipefail

target_root=${1:?usage: swarm-post.sh TARGET_ROOT PR RUN_ID STATUS SYNC_STARTED}
pr_number=${2:?usage: swarm-post.sh TARGET_ROOT PR RUN_ID STATUS SYNC_STARTED}
run_id=${3:?usage: swarm-post.sh TARGET_ROOT PR RUN_ID STATUS SYNC_STARTED}
run_status=${4:?usage: swarm-post.sh TARGET_ROOT PR RUN_ID STATUS SYNC_STARTED}
sync_started=${5:?usage: swarm-post.sh TARGET_ROOT PR RUN_ID STATUS SYNC_STARTED}

agent-relay cloud sync "$run_id" --dir "$target_root"

# shellcheck source=swarm-verdict.sh
source "$target_root/.review-gate/swarm-verdict.sh"
rows=$(mktemp)
trap 'rm -f "$rows"' EXIT
overall=REVIEW_PASSED
if ! swarm_evaluate "$target_root" "$pr_number" "$sync_started" > "$rows"; then
overall=REVIEW_FAILED
fi

upsert_comment() {
local anchor=$1 body_file=$2 comment_id
comment_id=$(gh api \
"repos/$GITHUB_REPOSITORY/issues/$pr_number/comments?per_page=100" \
--jq ".[] | select(.body | contains(\"$anchor\")) | .id" | sed -n '1p')
if [[ -n "$comment_id" ]]; then
gh api --method PATCH "repos/$GITHUB_REPOSITORY/issues/comments/$comment_id" \
-F "body=@$body_file" >/dev/null
else
gh pr comment "$pr_number" --repo "$GITHUB_REPOSITORY" \
--body-file "$body_file" >/dev/null
fi
}

marker=$(mktemp)
trap 'rm -f "$rows" "$marker"' EXIT
{
echo '<!-- review-swarm -->'
echo "Review swarm run \`$run_id\`: **$overall** (cloud status: \`$run_status\`)."
} > "$marker"
upsert_comment '<!-- review-swarm -->' "$marker"

while IFS=$'\t' read -r lens verdict transcript; do
body=$(mktemp)
{
echo "<!-- swarm-lens: $lens -->"
echo "### Review swarm: $lens"
echo
echo "Verdict: **$verdict**"
echo
if [[ "$transcript" != - ]]; then
cat "$transcript"
else
echo '_No transcript was produced by this run._'
fi
} > "$body"
upsert_comment "<!-- swarm-lens: $lens -->" "$body"
rm -f "$body"
done < "$rows"

echo "overall=$overall" >> "${GITHUB_OUTPUT:?GITHUB_OUTPUT is required}"
33 changes: 33 additions & 0 deletions .github/workflows/scripts/swarm-prepare.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -euo pipefail

gate_root=${1:?usage: swarm-prepare.sh GATE_ROOT TARGET_ROOT PR_NUMBER}
target_root=${2:?usage: swarm-prepare.sh GATE_ROOT TARGET_ROOT PR_NUMBER}
pr_number=${3:?usage: swarm-prepare.sh GATE_ROOT TARGET_ROOT PR_NUMBER}

[[ "$pr_number" =~ ^[1-9][0-9]*$ ]] || {
echo "PREPARE_FAILED: invalid PR number: $pr_number" >&2
exit 64
}

mkdir -p "$target_root/.review-target" "$target_root/.review-gate"
printf '%s\n' "$pr_number" > "$target_root/.review-target/pr-number"
date +%s > "$target_root/.review-target/sync-started"
gh pr diff "$pr_number" --repo "$GITHUB_REPOSITORY" \
> "$target_root/.review-target/pr.diff"
gh pr view "$pr_number" --repo "$GITHUB_REPOSITORY" \
--json headRefName,headRefOid,title,url \
> "$target_root/.review-target/pr.json"

# Only main's separately checked-out gate files enter the executable bundle.
cp "$gate_root/workflows/review-swarm.yaml" "$target_root/.review-gate/review-swarm.yaml"
cp "$gate_root/.github/workflows/scripts/swarm-verdict.sh" \
"$target_root/.review-gate/swarm-verdict.sh"

git -C "$target_root" add -f .review-target .review-gate
for evidence in pr-number sync-started pr.diff pr.json; do
git -C "$target_root" ls-files --error-unmatch ".review-target/$evidence" >/dev/null || {
echo "PREPARE_FAILED: .review-target/$evidence was not staged" >&2
exit 70
}
done
50 changes: 50 additions & 0 deletions .github/workflows/scripts/swarm-verdict.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/bin/sh

# Shared, fail-closed transcript selection and verdict extraction.

swarm_find_transcript() {
local root=$1 pr=$2 lens=$3
find "$root/ops/reviews" -maxdepth 1 -type f \
-name "*-pr${pr}-${lens}.md" -printf '%f\n' 2>/dev/null \
| LC_ALL=C sort | tail -n 1
}

swarm_transcript_verdict() {
local transcript=$1 terminal
terminal=$(sed '/^[[:space:]]*$/d' "$transcript" | tail -n 1)
terminal=${terminal#${terminal%%[![:space:]]*}}
terminal=${terminal%${terminal##*[![:space:]]}}
case "$terminal" in
REVIEW_PASSED|REVIEW_FAILED) printf '%s\n' "$terminal" ;;
*) printf '%s\n' REVIEW_UNCLEAR ;;
esac
}

# Prints one tab-separated row per lens: lens, verdict, absolute transcript.
swarm_evaluate() {
local root=$1 pr=$2 sync_started=${3:-0}
local lens name path verdict modified overall=0

for lens in maintainability history structure; do
name=$(swarm_find_transcript "$root" "$pr" "$lens")
if [ -z "$name" ]; then
printf '%s\t%s\t%s\n' "$lens" REVIEW_MISSING -
overall=1
continue
fi

path="$root/ops/reviews/$name"
modified=$(stat -c %Y "$path")
if [ "$modified" -lt "$sync_started" ]; then
printf '%s\t%s\t%s\n' "$lens" REVIEW_STALE "$path"
overall=1
continue
fi

verdict=$(swarm_transcript_verdict "$path")
printf '%s\t%s\t%s\n' "$lens" "$verdict" "$path"
[ "$verdict" = REVIEW_PASSED ] || overall=1
done

return "$overall"
}
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +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;
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@ 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.

## Review swarm cloud authentication

The `Review swarm` GitHub Actions workflow requires a repository Actions secret
named `RELAY_WORKSPACE_KEY`. Obtain the key from the Agent Relay workspace used
for this repository, then add it under **Settings → Secrets and variables →
Actions → New repository secret**. The workflow validates that the secret is
non-empty before launching a cloud run and fails immediately when it is absent.
Loading
Loading