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
92 changes: 92 additions & 0 deletions .github/actions/dispatch-live-proofs/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
name: Dispatch recommended live proofs
description: Dispatch enabled live-proof plans from durably published review records.
inputs:
target-repo:
description: Repository whose review records should be inspected.
required: true
item-numbers:
description: Comma-separated item numbers whose records were published.
required: true
records-root:
description: Root directory containing canonical review records.
required: true
client-id:
description: ClawSweeper GitHub App client ID.
required: true
private-key:
description: ClawSweeper GitHub App private key.
required: true
runs:
using: composite
steps:
- name: Select recommended live proofs
id: candidates
shell: bash
env:
ITEM_NUMBERS: ${{ inputs.item-numbers }}
RECORDS_ROOT: ${{ inputs.records-root }}
TARGET_REPO: ${{ inputs.target-repo }}
run: |
set -euo pipefail
candidates="$RUNNER_TEMP/clawsweeper-live-proof-candidates.jsonl"
: > "$candidates"
echo "path=$candidates" >> "$GITHUB_OUTPUT"
if [ ! -d "$RECORDS_ROOT" ]; then
echo "No records root exists at $RECORDS_ROOT; live-proof dispatch is a no-op."
echo "available=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ -z "${ITEM_NUMBERS//[[:space:],]/}" ]; then
echo "No published item numbers were provided; live-proof dispatch is a no-op."
echo "available=false" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ ! -f dist/repair/live-proof-dispatch-candidates.js ]; then
echo "dispatch-live-proofs requires dist/repair/live-proof-dispatch-candidates.js; run the build:repair script before this action." >&2
exit 1
fi
pnpm run --silent repair:live-proof-candidates > "$candidates"
if [ ! -s "$candidates" ]; then
echo "No published review requested an enabled live proof."
echo "available=false" >> "$GITHUB_OUTPUT"
exit 0
fi
echo "available=true" >> "$GITHUB_OUTPUT"

- name: Create live-proof dispatch token
id: dispatch-token
if: ${{ steps.candidates.outputs.available == 'true' }}
continue-on-error: true
uses: ./.github/actions/create-target-write-token
with:
client-id: ${{ inputs.client-id }}
private-key: ${{ inputs.private-key }}
owner: openclaw
repository: clawsweeper

- name: Dispatch recommended live proofs
if: ${{ steps.candidates.outputs.available == 'true' && steps.dispatch-token.outcome == 'success' && steps.dispatch-token.outputs.token != '' }}
shell: bash
env:
CANDIDATES_PATH: ${{ steps.candidates.outputs.path }}
GH_TOKEN: ${{ steps.dispatch-token.outputs.token }}
TARGET_REPO: ${{ inputs.target-repo }}
run: |
set -euo pipefail
while IFS= read -r candidate; do
item="$(jq -r '.item' <<<"$candidate")"
plan="$(jq -c '.plan' <<<"$candidate")"
jq -n \
--arg repo "$TARGET_REPO" \
--arg item "$item" \
--argjson plan "$plan" \
'{
event_type: "clawsweeper_live_proof",
client_payload: {
repo: $repo,
item: $item,
live_proof_plan: $plan
}
}' | gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" --input -
echo "Dispatched live proof for $TARGET_REPO#$item."
done < "$CANDIDATES_PATH"
69 changes: 69 additions & 0 deletions .github/workflows/exact-review-batch-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ jobs:
}}
runs-on: ubuntu-latest
timeout-minutes: 60
outputs:
live_proof_matrix: ${{ steps.live-proof-dispatch-matrix.outputs.matrix }}
env:
EXACT_REVIEW_QUEUE_URL: ${{ vars.CLAWSWEEPER_EXACT_REVIEW_QUEUE_URL || 'https://clawsweeper.openclaw.ai' }}
CLAWSWEEPER_AUTO_CLOSE_REASONS: ${{ vars.CLAWSWEEPER_AUTO_CLOSE_REASONS || 'all' }}
Expand Down Expand Up @@ -404,6 +406,32 @@ jobs:
pnpm run --silent repair:exact-review-batch observe || true
pnpm run --silent repair:exact-review-batch complete

- name: Compose live-proof dispatch matrix from durable batch receipt
id: live-proof-dispatch-matrix
if: ${{ steps.batch.outputs.claimed == 'true' && steps.batch.outputs.item_count != '0' }}
run: |
set -euo pipefail
receipt_path="$(dirname "$EXACT_REVIEW_BATCH_MANIFEST")/state-receipt.json"
matrix="$(jq -c '
[
.outcomes[]?
| select(.outcome == "accepted" or .outcome == "deduped")
| .canonicalTargetKey
| capture("^(?<target_repo>[^#]+)#(?<item_number>[1-9][0-9]*)$")
]
| unique_by(.target_repo, .item_number)
| sort_by(.target_repo, (.item_number | tonumber))
| group_by(.target_repo)
| {
include: map({
target_repo: .[0].target_repo,
target_slug: (.[0].target_repo | gsub("[^A-Za-z0-9_.-]+"; "-")),
item_numbers: (map(.item_number) | join(","))
})
}
' "$receipt_path")"
echo "matrix=$matrix" >> "$GITHUB_OUTPUT"

- name: Submit batch GitHub egress telemetry
if: ${{ always() && steps.github-egress-observer.outcome == 'success' }}
continue-on-error: true
Expand All @@ -417,3 +445,44 @@ jobs:
env:
CLAWSWEEPER_WEBHOOK_SECRET: ${{ secrets.CLAWSWEEPER_WEBHOOK_SECRET }}
run: pnpm run --silent repair:exact-review-batch release

dispatch-live-proofs:
name: Dispatch live proofs for ${{ matrix.target_repo }}
needs: publish
if: ${{ needs.publish.outputs.live_proof_matrix != '' && needs.publish.outputs.live_proof_matrix != '{"include":[]}' }}
strategy:
fail-fast: false
matrix: ${{ fromJSON(needs.publish.outputs.live_proof_matrix) }}
runs-on: ubuntu-latest
timeout-minutes: 15
env:
CLAWSWEEPER_APP_CLIENT_ID: Iv23liOECG0slfuhz093
steps:
- uses: actions/checkout@v7
with:
ref: main
filter: blob:none
fetch-depth: 1
persist-credentials: false

- uses: ./.github/actions/setup-pnpm
with:
build-script: build:repair

- uses: ./.github/actions/setup-state
with:
coordinator-url: ${{ vars.CLAWSWEEPER_EXACT_REVIEW_QUEUE_URL || 'https://clawsweeper.openclaw.ai' }}
records-url: ${{ vars.CLAWSWEEPER_EXACT_REVIEW_QUEUE_URL || 'https://clawsweeper.openclaw.ai' }}
records-secret: ${{ secrets.CLAWSWEEPER_WEBHOOK_SECRET }}
records-repo-slugs: ${{ matrix.target_slug }}
hydrate-git-state: "false"
hydrate-state-blobs: "false"

- name: Dispatch recommended live proofs
uses: ./.github/actions/dispatch-live-proofs
with:
target-repo: ${{ matrix.target_repo }}
item-numbers: ${{ matrix.item_numbers }}
records-root: records
client-id: ${{ env.CLAWSWEEPER_APP_CLIENT_ID }}
private-key: ${{ secrets.CLAWSWEEPER_APP_PRIVATE_KEY }}
92 changes: 28 additions & 64 deletions .github/workflows/sweep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1433,48 +1433,15 @@ jobs:
EXACT_REVIEW_BATCH_MUTATION_OUTPUT: .artifacts/direct-publication-outcome.json
run: pnpm run --silent repair:publish-event-result

- name: Create live-proof dispatch token
id: live-proof-dispatch-token
- name: Dispatch recommended live proofs
if: ${{ steps.claim-exact-review-queue.outputs.claimed == 'true' && steps.prepare-direct-exact-review-publication.outcome == 'success' }}
continue-on-error: true
uses: ./.github/actions/create-target-write-token
uses: ./.github/actions/dispatch-live-proofs
with:
target-repo: ${{ steps.target.outputs.target_repo }}
item-numbers: ${{ steps.target.outputs.item_number }}
records-root: records
client-id: ${{ env.CLAWSWEEPER_APP_CLIENT_ID }}
private-key: ${{ secrets.CLAWSWEEPER_APP_PRIVATE_KEY }}
owner: openclaw
repository: clawsweeper

- name: Dispatch recommended live proofs
if: ${{ steps.claim-exact-review-queue.outputs.claimed == 'true' && steps.prepare-direct-exact-review-publication.outcome == 'success' && steps.live-proof-dispatch-token.outcome == 'success' && steps.live-proof-dispatch-token.outputs.token != '' }}
env:
GH_TOKEN: ${{ steps.live-proof-dispatch-token.outputs.token }}
TARGET_REPO: ${{ steps.target.outputs.target_repo }}
ITEM_NUMBER: ${{ steps.target.outputs.item_number }}
run: |
set -euo pipefail
item_numbers="$ITEM_NUMBER"
ITEM_NUMBERS="$item_numbers" RECORDS_ROOT=records pnpm run --silent repair:live-proof-candidates > /tmp/live-proof-candidates.jsonl
if [ ! -s /tmp/live-proof-candidates.jsonl ]; then
echo "No published review requested an enabled live proof."
exit 0
fi
while IFS= read -r candidate; do
item="$(jq -r '.item' <<<"$candidate")"
plan="$(jq -c '.plan' <<<"$candidate")"
jq -n \
--arg repo "$TARGET_REPO" \
--arg item "$item" \
--argjson plan "$plan" \
'{
event_type: "clawsweeper_live_proof",
client_payload: {
repo: $repo,
item: $item,
live_proof_plan: $plan
}
}' | gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" --input -
echo "Dispatched live proof for $TARGET_REPO#$item."
done < /tmp/live-proof-candidates.jsonl

- name: Post direct exact review publication result
if: ${{ steps.claim-exact-review-queue.outputs.claimed == 'true' && steps.prepare-direct-exact-review-publication.outcome == 'success' }}
Expand Down Expand Up @@ -2629,6 +2596,16 @@ jobs:
fi
rm -f "$publication_error"

- name: Dispatch recommended live proofs
if: ${{ steps.publication-context.outputs.claimed == 'true' && steps.publication-context.outputs.direct_lifecycle_recovery != 'true' && steps.validate-exact-review-bundle.outcome == 'success' && steps.legacy-exact-artifact.outputs.legacy_tupleless != 'true' && steps.publish-event-result.outcome == 'success' && (steps.publish-event-result.outputs.remote_tuple_verified == 'true' || (steps.publish-event-result.outputs.completion_kind == 'deferred' && steps.publish-event-result.outputs.reason_code == 'close_coverage_deferred')) }}
uses: ./.github/actions/dispatch-live-proofs
with:
target-repo: ${{ steps.publication-context.outputs.target_repo }}
item-numbers: ${{ steps.publication-context.outputs.item_number }}
records-root: records
client-id: ${{ env.CLAWSWEEPER_APP_CLIENT_ID }}
private-key: ${{ secrets.CLAWSWEEPER_APP_PRIVATE_KEY }}

- name: Record fallback canonical exact review lifecycle receipt
id: record-fallback-canonical-lifecycle-receipt
if: ${{ steps.publication-context.outputs.claimed == 'true' && steps.publication-context.outputs.direct_lifecycle_recovery != 'true' && steps.publish-event-result.outcome == 'success' && (steps.publish-event-result.outputs.remote_tuple_verified == 'true' || (steps.publish-event-result.outputs.completion_kind == 'deferred' && steps.publish-event-result.outputs.reason_code == 'close_coverage_deferred')) }}
Expand Down Expand Up @@ -4788,36 +4765,23 @@ jobs:
--artifact-dir artifacts \
--report-dir "records/$target_slug/items"

- name: Dispatch recommended live proofs
- name: Collect published review item numbers
id: published-review-items
if: ${{ always() && !cancelled() && steps.commit-review-records.outputs.records_published == 'true' }}
env:
GH_TOKEN: ${{ github.token }}
TARGET_REPO: ${{ needs.plan.outputs.target_repo }}
run: |
set -euo pipefail
item_numbers="$(pnpm run --silent workflow -- artifact-item-numbers --artifact-dir artifacts)"
ITEM_NUMBERS="$item_numbers" RECORDS_ROOT=records pnpm run --silent repair:live-proof-candidates > /tmp/live-proof-candidates.jsonl
if [ ! -s /tmp/live-proof-candidates.jsonl ]; then
echo "No published review requested an enabled live proof."
exit 0
fi
while IFS= read -r candidate; do
item="$(jq -r '.item' <<<"$candidate")"
plan="$(jq -c '.plan' <<<"$candidate")"
jq -n \
--arg repo "$TARGET_REPO" \
--arg item "$item" \
--argjson plan "$plan" \
'{
event_type: "clawsweeper_live_proof",
client_payload: {
repo: $repo,
item: $item,
live_proof_plan: $plan
}
}' | gh api --method POST "repos/$GITHUB_REPOSITORY/dispatches" --input -
echo "Dispatched live proof for $TARGET_REPO#$item."
done < /tmp/live-proof-candidates.jsonl
echo "item_numbers=$item_numbers" >> "$GITHUB_OUTPUT"

- name: Dispatch recommended live proofs
if: ${{ always() && !cancelled() && steps.commit-review-records.outputs.records_published == 'true' && steps.published-review-items.outcome == 'success' }}
uses: ./.github/actions/dispatch-live-proofs
with:
target-repo: ${{ needs.plan.outputs.target_repo }}
item-numbers: ${{ steps.published-review-items.outputs.item_numbers }}
records-root: records
client-id: ${{ env.CLAWSWEEPER_APP_CLIENT_ID }}
private-key: ${{ secrets.CLAWSWEEPER_APP_PRIVATE_KEY }}

- name: Dispatch vision-fit implementation candidates
if: ${{ always() && !cancelled() && steps.commit-review-records.outputs.records_published == 'true' && vars.CLAWSWEEPER_AUTO_IMPLEMENT_ISSUES == '1' && needs.plan.outputs.target_repo == 'openclaw/openclaw' && vars.CLAWSWEEPER_AUTO_IMPLEMENT_VISION_FIT == '1' }}
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ checkpoint, and status-only commits are intentionally omitted.

### Fixed

- Routed every durable review-record publication lane through one shared, host-authenticated live-proof dispatcher, including queued exact-review batches grouped per target repository.
- Exact-event reviews now dispatch recommended live proofs with host-repository credentials, while generic and configured OpenClaw and steipete profiles opt into browser or terminal proof as appropriate.
- Hosted webhook 🦞👀 receipts now dedupe per pull request across `opened` and `ready_for_review`, so back-to-back webhook actions keep one receipt instead of posting near-identical duplicates. (#1084)
- The target dispatcher no longer double-posts pull request receipt acknowledgements when `opened` and `ready_for_review` fire seconds apart: the ack step now waits and rechecks for any existing marker immediately before posting. (#1083)
Expand Down
Loading
Loading