clawsweeper/scripts/restore-repair-job.sh
2026-05-03 15:44:14 +01:00

186 lines
5.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
JOB_PATH="${1:-${JOB_PATH:-}}"
SKIP_TARGET="${2:-this worker}"
if [ -z "$JOB_PATH" ]; then
echo "JOB_PATH is required" >&2
exit 1
fi
write_output() {
local key="$1"
local value="$2"
if [ -n "${GITHUB_OUTPUT:-}" ]; then
echo "$key=$value" >> "$GITHUB_OUTPUT"
else
echo "$key=$value"
fi
}
restore_automerge_job() {
case "$JOB_PATH" in
jobs/*/inbox/automerge-*.md) ;;
*) return 1 ;;
esac
local filename stem rest number repo_slug owner repo_name repo ref branch
filename="${JOB_PATH##*/}"
stem="${filename%.md}"
rest="${stem#automerge-}"
number="${rest##*-}"
repo_slug="${rest%-${number}}"
owner="${JOB_PATH#jobs/}"
owner="${owner%%/*}"
repo_name="${repo_slug#${owner}-}"
if [ -z "$number" ] || [ "$number" = "$rest" ] || [ -z "$repo_name" ] || [ "$repo_name" = "$repo_slug" ]; then
return 1
fi
repo="$owner/$repo_name"
ref="#$number"
branch="clawsweeper/automerge-$repo_slug-$number"
mkdir -p "$(dirname "$JOB_PATH")"
cat > "$JOB_PATH" <<EOF
---
repo: $repo
cluster_id: automerge-$repo_slug-$number
mode: autonomous
allowed_actions:
- comment
- label
- fix
- raise_pr
blocked_actions:
- close
- merge
require_human_for:
- close
- merge
canonical:
- $ref
candidates:
- $ref
cluster_refs:
- $ref
allow_instant_close: false
allow_fix_pr: true
allow_merge: false
allow_unmerged_fix_close: false
allow_post_merge_close: false
require_fix_before_close: true
security_policy: central_security_only
security_sensitive: false
target_branch: $branch
source: pr_automerge
---
# ClawSweeper adopted PR repair candidate
Maintainer opted $ref into ClawSweeper automerge.
Source PR: https://github.com/$repo/pull/$number
Title: PR $ref
ClawSweeper should use this job only for the bounded ClawSweeper review/fix loop:
- If ClawSweeper emits an explicit repair marker, requests changes, or finds failing checks/rebase work, and the PR branch is safe to update, emit a fix artifact with \`repair_strategy: "repair_contributor_branch"\` and \`source_prs: ["https://github.com/$repo/pull/$number"]\`.
- If the PR branch cannot be safely updated, emit a narrow credited replacement only when the artifact can preserve the original contributor credit; otherwise return \`needs_human\`.
- Do not merge, close, or bypass review gates from the worker. The comment router owns final merge only after a passing ClawSweeper verdict for the exact current head.
- Keep repair scope limited to actionable ClawSweeper findings, failing relevant checks, and required review feedback on this PR.
EOF
}
restore_issue_implementation_job() {
case "$JOB_PATH" in
jobs/*/inbox/issue-*.md) ;;
*) return 1 ;;
esac
local filename stem rest number repo_slug owner repo_name repo ref branch
filename="${JOB_PATH##*/}"
stem="${filename%.md}"
rest="${stem#issue-}"
number="${rest##*-}"
repo_slug="${rest%-${number}}"
owner="${JOB_PATH#jobs/}"
owner="${owner%%/*}"
repo_name="${repo_slug#${owner}-}"
if [ -z "$number" ] || [ "$number" = "$rest" ] || [ -z "$repo_name" ] || [ "$repo_name" = "$repo_slug" ]; then
return 1
fi
repo="$owner/$repo_name"
ref="#$number"
branch="clawsweeper/issue-$repo_slug-$number"
mkdir -p "$(dirname "$JOB_PATH")"
cat > "$JOB_PATH" <<EOF
---
repo: $repo
cluster_id: issue-$repo_slug-$number
mode: autonomous
allowed_actions:
- comment
- label
- fix
- raise_pr
blocked_actions:
- close
- merge
require_human_for:
- close
- merge
canonical:
- $ref
candidates:
- $ref
cluster_refs:
- $ref
allow_instant_close: false
allow_fix_pr: true
allow_merge: false
allow_unmerged_fix_close: false
allow_post_merge_close: false
require_fix_before_close: false
security_policy: central_security_only
security_sensitive: false
target_branch: $branch
source: issue_implementation
required_pr_labels:
- clawsweeper:autogenerated
---
# ClawSweeper issue implementation candidate
ClawSweeper Repair should create or update one implementation PR from \`$branch\`.
Source issue: https://github.com/$repo/issues/$number
Title: Issue $ref
## Operator Prompt
Use the source issue as the product request or bug report. Verify the request is still valid on latest \`$repo@main\`, inspect nearby code, and make the narrowest implementation that directly satisfies the issue. If the issue is too broad, underspecified, security-sensitive, already fixed, or not safely implementable by automation, do not change code; report the exact blocker.
When code changes are appropriate, emit a fix artifact with \`repair_strategy: "new_fix_pr"\`, \`source_prs: []\`, this issue in \`linked_refs\`, and validation commands for the touched surface.
## Guardrails
- Do not merge.
- Do not close the issue from this lane.
- Keep one PR for this issue; reuse \`$branch\` if it already exists.
- Keep the diff narrow and avoid unrelated refactors.
- Preserve issue context and link https://github.com/$repo/issues/$number in the PR body.
- Add a changelog entry when the target repo expects one.
EOF
}
if [ -f "$JOB_PATH" ]; then
write_output job_exists 1
elif restore_automerge_job; then
write_output job_exists 1
echo "::notice title=Restored automerge repair job::Job file '$JOB_PATH' was missing from the state checkout; reconstructed it from the workflow input."
elif restore_issue_implementation_job; then
write_output job_exists 1
echo "::notice title=Restored issue implementation job::Job file '$JOB_PATH' was missing from the state checkout; reconstructed it from the workflow input."
else
write_output job_exists 0
echo "::notice title=Stale repair dispatch::Job file '$JOB_PATH' no longer exists on the current state checkout; skipping $SKIP_TARGET."
fi