From f7f0fc92899843941fab61cdc5288e098657deec Mon Sep 17 00:00:00 2001 From: brokemac79 Date: Thu, 16 Jul 2026 02:32:21 +0100 Subject: [PATCH] fix: run exact publishers on current main --- .github/workflows/sweep.yml | 90 +++++++++---------- test/clawsweeper-action-ledger.test.ts | 3 +- test/repair/command-ops-action-ledger.test.ts | 24 +---- test/sweep-workflow.test.ts | 37 +++++--- 4 files changed, 70 insertions(+), 84 deletions(-) diff --git a/.github/workflows/sweep.yml b/.github/workflows/sweep.yml index 3a6dd9a5e3..c884ba00b4 100644 --- a/.github/workflows/sweep.yml +++ b/.github/workflows/sweep.yml @@ -1344,7 +1344,9 @@ jobs: - uses: actions/checkout@v7 if: ${{ steps.publication-context.outputs.claimed == 'true' }} with: - ref: ${{ steps.publication-context.outputs.source_sha }} + # The artifact validator binds the producer SHA. The publisher itself + # must run the current repaired implementation, not historical code. + ref: main filter: blob:none fetch-depth: 0 persist-credentials: false @@ -1393,6 +1395,33 @@ jobs: EXACT_REVIEW_TARGET_REPO: ${{ steps.publication-context.outputs.target_repo }} run: pnpm run --silent repair:exact-review-bundle validate + - name: Identify legacy tuple-less exact artifact + id: legacy-exact-artifact + if: ${{ steps.publication-context.outputs.claimed == 'true' }} + env: + REPORT_PATH: .artifacts/exact-review-bundle/review/${{ steps.publication-context.outputs.item_number }}.md + run: | + set -euo pipefail + REPORT_PATH="$REPORT_PATH" node <<'NODE' + const fs = require("node:fs"); + const reportPath = process.env.REPORT_PATH; + let legacyTupleless = false; + if (fs.existsSync(reportPath)) { + const markdown = fs.readFileSync(reportPath, "utf8"); + const owner = /^review_lease_owner:\s*(.+)\s*$/m.exec(markdown)?.[1]?.trim() || ""; + const commentId = Number( + /^review_lease_comment_id:\s*(\d+)\s*$/m.exec(markdown)?.[1] || "0", + ); + legacyTupleless = + (!owner || owner === "unknown") && + (!Number.isInteger(commentId) || commentId <= 0); + } + fs.appendFileSync( + process.env.GITHUB_OUTPUT, + `legacy_tupleless=${legacyTupleless ? "true" : "false"}\n`, + ); + NODE + - name: Stage validated exact review artifact if: ${{ steps.publication-context.outputs.claimed == 'true' }} run: | @@ -1420,7 +1449,7 @@ jobs: permission-statuses: read - name: Create state token - if: ${{ steps.publication-context.outputs.claimed == 'true' }} + if: ${{ steps.publication-context.outputs.claimed == 'true' && steps.legacy-exact-artifact.outputs.legacy_tupleless != 'true' }} id: state-token uses: ./.github/actions/create-state-token with: @@ -1428,14 +1457,14 @@ jobs: private-key: ${{ secrets.CLAWSWEEPER_APP_PRIVATE_KEY }} - uses: ./.github/actions/setup-state - if: ${{ steps.publication-context.outputs.claimed == 'true' }} + if: ${{ steps.publication-context.outputs.claimed == 'true' && steps.legacy-exact-artifact.outputs.legacy_tupleless != 'true' }} id: setup-state with: token: ${{ steps.state-token.outputs.token }} fetch-depth: 1 - name: Publish event result and apply safe close - if: ${{ steps.publication-context.outputs.claimed == 'true' }} + if: ${{ steps.publication-context.outputs.claimed == 'true' && steps.legacy-exact-artifact.outputs.legacy_tupleless != 'true' }} id: publish-event-result env: GH_TOKEN: ${{ steps.target-write-token.outputs.token }} @@ -1571,7 +1600,7 @@ jobs: - name: Queue fresh review after source drift id: queue-source-drift-review - if: ${{ steps.publication-context.outputs.claimed == 'true' && steps.publish-event-result.outputs.requeue_latest == 'true' }} + if: ${{ steps.publication-context.outputs.claimed == 'true' && (steps.publish-event-result.outputs.requeue_latest == 'true' || steps.legacy-exact-artifact.outputs.legacy_tupleless == 'true') }} env: CLAIM_DECISION: ${{ steps.publication-context.outputs.decision }} PRODUCER_RUN_ATTEMPT: ${{ steps.publication-context.outputs.generation_attempt }} @@ -1663,6 +1692,7 @@ jobs: ROUTING_DEFERRED: ${{ steps.publish-event-result.outputs.routing_deferred }} POLICY_NOOP: ${{ steps.publish-event-result.outputs.policy_noop }} REQUEUE_LATEST: ${{ steps.publish-event-result.outputs.requeue_latest }} + LEGACY_TUPLELESS: ${{ steps.legacy-exact-artifact.outputs.legacy_tupleless }} REVIEW_ONLY: ${{ fromJSON(steps.publication-context.outputs.decision).sourceAction == 'failed_review_shard_recovery' && 'true' || 'false' }} run: | state="Failed" @@ -1670,6 +1700,9 @@ jobs: if [ "$POLICY_NOOP" = "true" ]; then state="Complete" detail="The exact review reached a deterministic policy veto; no action was taken." + elif [ "$LEGACY_TUPLELESS" = "true" ] && [ "${{ steps.queue-source-drift-review.outcome }}" = "success" ]; then + state="Complete" + detail="The legacy artifact lacked its durable review lease tuple; one fresh exact review was queued." elif [ "$REQUEUE_LATEST" = "true" ] && [ "${{ steps.queue-source-drift-review.outcome }}" = "success" ]; then state="Complete" detail="The item changed after review; one fresh exact review was queued." @@ -1722,48 +1755,6 @@ jobs: gh api "repos/$TARGET_REPO/issues/$ITEM_NUMBER/reactions/$reaction_id" --method DELETE || true done <<< "$reaction_ids" - - name: Publish exact review action ledger - if: ${{ always() && steps.publication-context.outputs.claimed == 'true' && steps.setup-state.outcome == 'success' }} - continue-on-error: true - env: - GENERATION_ATTEMPT: ${{ steps.publication-context.outputs.generation_attempt }} - run: | - set -euo pipefail - test -n "${CLAWSWEEPER_STATE_DIR:-}" - mkdir -p .artifacts - event_paths_file=".artifacts/exact-review-action-ledger-paths.txt" - : > "$event_paths_file" - source_root=".artifacts/exact-review-bundle/action-ledger" - if [ -d "$source_root/ledger" ]; then - pnpm run --silent publish-action-events -- \ - --source-root "$source_root" \ - --state-root "$CLAWSWEEPER_STATE_DIR" \ - --expected-producer-job event-review-apply \ - --expected-producer-run-id "${{ steps.publication-context.outputs.producer_run_id }}" \ - --expected-producer-sha "${{ steps.publication-context.outputs.source_sha }}" \ - --expected-producer-run-attempt "$GENERATION_ATTEMPT" | jq -r '.paths[]?' >> "$event_paths_file" - fi - publisher_ledger_root="${CLAWSWEEPER_ACTION_LEDGER_OUTPUT_ROOT:-}" - if [ -n "$publisher_ledger_root" ] && [ -d "$publisher_ledger_root/ledger" ]; then - pnpm run --silent publish-action-events -- \ - --source-root "$publisher_ledger_root" \ - --state-root "$CLAWSWEEPER_STATE_DIR" \ - --expected-producer-job "$GITHUB_JOB" | jq -r '.paths[]?' >> "$event_paths_file" - fi - sort -u -o "$event_paths_file" "$event_paths_file" - if [ ! -s "$event_paths_file" ]; then - echo "No exact review action events to publish." - exit 0 - fi - while IFS= read -r event_path; do - test -f "$CLAWSWEEPER_STATE_DIR/$event_path" - mkdir -p "$(dirname "$event_path")" - cp "$CLAWSWEEPER_STATE_DIR/$event_path" "$event_path" - done < "$event_paths_file" - node dist/clawsweeper.js publish-action-event-paths \ - --paths-file "$event_paths_file" \ - --message "chore: append exact review action ledger" - - name: Release unsuccessful publisher-owned review lease if: ${{ always() && steps.publication-context.outputs.claimed == 'true' && steps.publication-context.outputs.live_proceeded == 'true' && (steps.publish-event-result.outcome != 'success' || (steps.publish-event-result.outputs.requeue_latest == 'true' && steps.queue-source-drift-review.outcome != 'success')) }} env: @@ -1799,12 +1790,15 @@ jobs: GUARDED_OPEN: ${{ steps.publish-event-result.outputs.guarded_open }} POLICY_NOOP: ${{ steps.publish-event-result.outputs.policy_noop }} REQUEUE_LATEST: ${{ steps.publish-event-result.outputs.requeue_latest }} + LEGACY_TUPLELESS: ${{ steps.legacy-exact-artifact.outputs.legacy_tupleless }} SOURCE_DRIFT_OUTCOME: ${{ steps.queue-source-drift-review.outcome }} DEFERRED_ROUTE_OUTCOME: ${{ steps.queue-deferred-verdict-router.outcome }} REVIEW_ONLY: ${{ fromJSON(steps.publication-context.outputs.decision).sourceAction == 'failed_review_shard_recovery' && 'true' || 'false' }} run: | outcome=failure - if [ "$PRIOR_JOB_STATUS" = "cancelled" ]; then + if [ "$LEGACY_TUPLELESS" = "true" ] && [ "$SOURCE_DRIFT_OUTCOME" = "success" ]; then + outcome=success + elif [ "$PRIOR_JOB_STATUS" = "cancelled" ]; then outcome=cancelled elif [ "$PRIOR_JOB_STATUS" = "success" ]; then if [ "$PUBLISH_OUTCOME" = "success" ] && [ "$REQUEUE_LATEST" = "true" ] && [ "$SOURCE_DRIFT_OUTCOME" = "success" ]; then diff --git a/test/clawsweeper-action-ledger.test.ts b/test/clawsweeper-action-ledger.test.ts index 726b61c351..af7887f68d 100644 --- a/test/clawsweeper-action-ledger.test.ts +++ b/test/clawsweeper-action-ledger.test.ts @@ -785,7 +785,6 @@ test("sweep publishes complete immutable shards for every review and apply produ "Publish selected review comment action ledger", "Publish failed-review retry action ledger", "Finalize exact event action ledger", - "Publish exact review action ledger", "Finalize apply proof action ledger", "Publish apply proof action events", "Publish apply action events", @@ -801,7 +800,7 @@ test("sweep publishes complete immutable shards for every review and apply produ assert.match(workflow, /include-hidden-files: true/); assert.match(workflow, /--state-root "\$CLAWSWEEPER_STATE_DIR"/); assert.match(workflow, /durable_event_path="\$CLAWSWEEPER_STATE_DIR\/\$event_path"/); - assert.equal((workflow.match(/publish-action-event-paths/g) ?? []).length, 7); + assert.equal((workflow.match(/publish-action-event-paths/g) ?? []).length, 6); assert.doesNotMatch( workflow, /--message "chore: append (?:review|apply).*action ledger"[\s\S]{0,180}--path "ledger\/v1\/events"/, diff --git a/test/repair/command-ops-action-ledger.test.ts b/test/repair/command-ops-action-ledger.test.ts index debf20397e..4aba43101b 100644 --- a/test/repair/command-ops-action-ledger.test.ts +++ b/test/repair/command-ops-action-ledger.test.ts @@ -76,9 +76,7 @@ test("direct repair requeues forward a stable dispatch receipt and publish it", assert.match(workflow, /--max-requeue-depth 1/); }); -test("exact review publisher includes command status receipts after the status mutation", () => { - const setupAction = readText(".github/actions/setup-action-ledger/action.yml"); - const source = readText("src/repair/update-command-status.ts"); +test("exact review publisher bypasses the legacy action ledger", () => { const workflow = readText(".github/workflows/sweep.yml"); const publisherJob = workflow.indexOf("\n event-review-publish:"); const statusMutation = workflow.indexOf("- name: Mark re-review complete", publisherJob); @@ -86,28 +84,10 @@ test("exact review publisher includes command status receipts after the status m "- name: Publish exact review action ledger", publisherJob, ); - const nextStep = workflow.indexOf( - "- name: Release unsuccessful publisher-owned review lease", - ledgerPublish, - ); - const publishStep = workflow.slice(ledgerPublish, nextStep); assert.ok(publisherJob >= 0); assert.ok(statusMutation > publisherJob); - assert.ok(ledgerPublish > statusMutation); - assert.ok(nextStep > ledgerPublish); - assert.match(setupAction, /CLAWSWEEPER_ACTION_LEDGER_OUTPUT_ROOT=\$output_root/); - assert.match(source, /await flushCommandActionEvents\(\)/); - assert.match(publishStep, /if: \$\{\{ always\(\)[^\n]*\}\}/); - assert.match(publishStep, /steps\.publication-context\.outputs\.claimed == 'true'/); - assert.match(publishStep, /steps\.setup-state\.outcome == 'success'/); - assert.match(publishStep, /continue-on-error: true/); - assert.match(publishStep, /source_root="\.artifacts\/exact-review-bundle\/action-ledger"/); - assert.match(publishStep, /CLAWSWEEPER_ACTION_LEDGER_OUTPUT_ROOT:-/); - assert.match(publishStep, /publisher_ledger_root\/ledger/); - assert.match(publishStep, /--expected-producer-job "\$GITHUB_JOB"/); - assert.match(publishStep, /sort -u -o "\$event_paths_file" "\$event_paths_file"/); - assert.match(publishStep, /--message "chore: append exact review action ledger"/); + assert.equal(ledgerPublish, -1); }); function assertCommandFinalizerUsesCanonicalRoot(step: string): void { diff --git a/test/sweep-workflow.test.ts b/test/sweep-workflow.test.ts index 55cdcd1a29..b3b55b10a6 100644 --- a/test/sweep-workflow.test.ts +++ b/test/sweep-workflow.test.ts @@ -130,7 +130,6 @@ test("review and apply primary boundaries ignore ledger-only failures", () => { "event-review-apply", "Queue durable exact review publication", ); - const exactLedger = step("event-review-publish", "Publish exact review action ledger"); const exactSteps = job("event-review-apply").steps; assert.match(exactPrimary.run ?? "", /outcome=(?:failure|cancelled|success)/); assert.match(exactPrimary.run ?? "", /REVIEW_OUTCOME.*cancelled/); @@ -141,7 +140,12 @@ test("review and apply primary boundaries ignore ledger-only failures", () => { assert.ok(exactSteps.indexOf(exactUpload) < exactSteps.indexOf(exactPublicationQueue)); assert.ok(exactSteps.indexOf(exactPublicationQueue) < exactSteps.indexOf(exactQueue)); assert.ok(exactSteps.indexOf(exactQueue) > exactSteps.indexOf(exactPrimary)); - assert.match(exactLedger.run ?? "", /expected-producer-run-attempt/); + assert.equal( + job("event-review-publish").steps.some( + (candidate) => candidate.name === "Publish exact review action ledger", + ), + false, + ); const ledgerDownload = job("publish").steps.find( (candidate) => candidate.id === "download-review-action-ledger", @@ -438,9 +442,15 @@ test("exact event review hands immutable artifacts to the queue-bounded publishe const download = step(publisher, "Download exact review artifact bundle"); const validate = step(publisher, "Validate exact review artifact bundle"); + const legacyArtifact = step(publisher, "Identify legacy tuple-less exact artifact"); const targetWriteStep = step(publisher, "Create target write token"); const stateSetup = publisher.steps.find((candidate) => candidate.uses?.endsWith("/setup-state")); assert.ok(stateSetup); + const publisherCheckout = publisher.steps.find( + (candidate) => candidate.uses === "actions/checkout@v7", + ); + assert.ok(publisherCheckout); + assert.equal(publisherCheckout.with?.ref, "main"); assert.equal(download.uses, "actions/download-artifact@v8"); assert.equal(download.with?.name, "${{ steps.publication-context.outputs.artifact_name }}"); assert.equal( @@ -448,10 +458,13 @@ test("exact event review hands immutable artifacts to the queue-bounded publishe "${{ steps.publication-context.outputs.producer_run_id }}", ); assert.match(validate.run ?? "", /repair:exact-review-bundle validate/); + assert.match(legacyArtifact.run ?? "", /review_lease_owner/); + assert.match(legacyArtifact.run ?? "", /review_lease_comment_id/); assert.doesNotMatch(create.run ?? "", /repair:exact-review-bundle -- create/); assert.doesNotMatch(validate.run ?? "", /repair:exact-review-bundle -- validate/); assert.ok(publisher.steps.indexOf(validate) < publisher.steps.indexOf(targetWriteStep)); assert.ok(publisher.steps.indexOf(validate) < publisher.steps.indexOf(stateSetup)); + assert.match(stateSetup.if ?? "", /legacy-exact-artifact\.outputs\.legacy_tupleless != 'true'/); const publish = step(publisher, "Publish event result and apply safe close"); assert.match(publish.run ?? "", /live_state=.*gh api/); @@ -473,6 +486,7 @@ test("exact event review hands immutable artifacts to the queue-bounded publishe assert.match(deferredRoute.run ?? "", /repair-comment-router\.yml/); const drift = step(publisher, "Queue fresh review after source drift"); assert.match(drift.if ?? "", /requeue_latest == 'true'/); + assert.match(drift.if ?? "", /legacy-exact-artifact\.outputs\.legacy_tupleless == 'true'/); assert.match(drift.run ?? "", /x-clawsweeper-exact-review-signature/); assert.match(drift.run ?? "", /internal\/exact-review\/enqueue/); assert.match(drift.run ?? "", /decision\.sourceAction === "failed_review_shard_recovery"/); @@ -484,13 +498,10 @@ test("exact event review hands immutable artifacts to the queue-bounded publishe const reaction = step(publisher, "React to target item completion"); assert.match(reaction.if ?? "", /requeue_latest != 'true'/); assert.doesNotMatch(reaction.if ?? "", /publication-context.*live_guarded_open/); - const ledger = step(publisher, "Publish exact review action ledger"); - assert.equal(ledger["continue-on-error"], true); - assert.match(ledger.run ?? "", /CLAWSWEEPER_ACTION_LEDGER_OUTPUT_ROOT:-/); - assert.match(ledger.run ?? "", /--expected-producer-job event-review-apply/); - assert.match(ledger.run ?? "", /--expected-producer-run-id/); - assert.match(ledger.run ?? "", /--expected-producer-sha/); - assert.match(ledger.run ?? "", /--expected-producer-run-attempt "\$GENERATION_ATTEMPT"/); + assert.equal( + publisher.steps.some((candidate) => candidate.name === "Publish exact review action ledger"), + false, + ); const publishResult = step(publisher, "Export exact review publication result"); const publishComplete = step(publisher, "Complete durable exact review publication"); const releaseTerminal = step(publisher, "Release terminal review leases"); @@ -500,7 +511,9 @@ test("exact event review hands immutable artifacts to the queue-bounded publishe assert.match(releaseUnsuccessful.run ?? "", /\.user\.login == \\"clawsweeper\[bot\]\\"/); assert.match(releaseUnsuccessful.run ?? "", /content == "eyes"/); assert.match(publishResult.env?.PRIOR_JOB_STATUS ?? "", /job\.status/); + assert.match(publishResult.env?.LEGACY_TUPLELESS ?? "", /legacy-exact-artifact/); assert.match(publishResult.run ?? "", /REQUEUE_LATEST.*SOURCE_DRIFT_OUTCOME/); + assert.match(publishResult.run ?? "", /LEGACY_TUPLELESS.*SOURCE_DRIFT_OUTCOME/); assert.doesNotMatch(publishResult.run ?? "", /LIVE_TERMINAL_NOOP/); assert.match(publishComplete.run ?? "", /internal\/exact-review\/complete/); assert.ok(publisher.steps.indexOf(publishResult) < publisher.steps.indexOf(publishComplete)); @@ -1748,8 +1761,8 @@ test("trusted comment router owns command ledger capacity retries", () => { const eventEnd = sweepWorkflow.indexOf("\n target-fanout:", eventStart); const eventJob = sweepWorkflow.slice(eventStart, eventEnd); - assert.match(eventJob, /publish-action-events/); - assert.match(eventJob, /publish-action-event-paths/); + assert.doesNotMatch(eventJob, /publish-action-events/); + assert.doesNotMatch(eventJob, /publish-action-event-paths/); assert.doesNotMatch(eventJob, /count-command-actions/); assert.doesNotMatch(eventJob, /--wait-for-capacity/); assert.match(routerWorkflow, /Commit comment router ledger/); @@ -2300,7 +2313,7 @@ test("every action-ledger publication authenticates the expected producer job", /pnpm run --silent publish-action-events -- \\\n(?:\s+.*\\\n)*\s+--expected-producer-job [^\n]+/g, ); assert.ok(commands); - assert.equal(commands.length, 9); + assert.equal(commands.length, 7); assert.ok(commands.every((command) => command.includes("--expected-producer-job"))); assert.match(workflow, /--expected-producer-job review/); assert.match(workflow, /--expected-producer-job apply-proof/);