From 2adcf6015a4cdb05370cca2e3cf02502e4e76f6b Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Fri, 1 May 2026 10:42:24 -0700 Subject: [PATCH] fix(workflow): recover review shards without red runs --- .github/workflows/sweep.yml | 54 ++++++++++++++++++++++++++++++------- test/clawsweeper.test.ts | 15 +++++++++++ 2 files changed, 60 insertions(+), 9 deletions(-) diff --git a/.github/workflows/sweep.yml b/.github/workflows/sweep.yml index 0433bd2759..4a80b47047 100644 --- a/.github/workflows/sweep.yml +++ b/.github/workflows/sweep.yml @@ -703,6 +703,8 @@ jobs: git -C "$checkout_dir" rev-parse --short HEAD - name: Review shard + id: review-shard + continue-on-error: true working-directory: clawsweeper env: GH_TOKEN: ${{ steps.target-read-token.outputs.token }} @@ -734,6 +736,17 @@ jobs: --shard-count ${{ needs.plan.outputs.planned_shards }} \ "${additional_prompt_arg[@]}" + - name: Record failed review shard + if: ${{ steps.review-shard.outcome == 'failure' }} + run: | + mkdir -p review-artifacts/failed-shards + cat > review-artifacts/failed-shards/shard-${{ matrix.shard }}.json < { } }); +test("sweep review recovery uses explicit failed shard artifacts", () => { + const workflow = readFileSync(".github/workflows/sweep.yml", "utf8"); + + assert.match(workflow, /- name: Review shard\n\s+id: review-shard\n\s+continue-on-error: true/); + assert.match(workflow, /- name: Record failed review shard/); + assert.match(workflow, /steps\.review-shard\.outcome == 'failure'/); + assert.match(workflow, /name: review-failed-shard-\$\{\{ matrix\.shard \}\}/); + assert.match(workflow, /pattern: review-failed-shard-\*/); + assert.match(workflow, /needs\.review\.result != 'skipped'/); + assert.doesNotMatch( + workflow, + /needs\.review\.result == 'failure' \|\| needs\.review\.result == 'cancelled'/, + ); +}); + test("review parser strips environment access caveats from risks", () => { const parsed = parseDecision( closeDecision({