diff --git a/.github/ai/README.md b/.github/ai/README.md index 710cc00e09..e6702d07a7 100644 --- a/.github/ai/README.md +++ b/.github/ai/README.md @@ -12,10 +12,10 @@ maintainer. 3. Reports missing essential evidence receive focused questions. 4. New add-on requests are marked for maintainer review and are never implemented by this automation. -5. High-confidence improvements to existing add-ons proceed automatically to a - draft fix attempt. -6. Bugs opened by the repository owner proceed directly to Codex analysis; - other bugs wait for a maintainer to add `ai: fix-approved`. +5. High-confidence bugs and existing-add-on improvements opened by the + repository owner proceed directly to Codex analysis; those opened by anyone + else wait for a maintainer to add `ai: fix-approved`. +6. New add-on requests never enter Codex, regardless of who opens them. 7. Codex edits an isolated checkout without repository write permissions. 8. A fresh job applies and validates the patch, pushes a branch, opens a draft pull request, and posts the root-cause report and pull-request URL. diff --git a/.github/scripts/validate_ai_patch.sh b/.github/scripts/validate_ai_patch.sh index 7391cd0420..538b37f670 100644 --- a/.github/scripts/validate_ai_patch.sh +++ b/.github/scripts/validate_ai_patch.sh @@ -84,6 +84,11 @@ for file in "${changed_files[@]}"; do echo "Creating a new top-level directory is not permitted: $top" >&2 exit 1 fi + else + if ! git cat-file -e "$base_ref:$file" 2>/dev/null; then + echo "Creating a new top-level file is not permitted: $file" >&2 + exit 1 + fi fi if [[ "$request_category" == "improvement" && -n "$expected_addon" && "$file" != "$expected_addon/"* ]]; then diff --git a/.github/workflows/on_issues_ai.yml b/.github/workflows/on_issues_ai.yml index f47d051e65..58e7477bc0 100644 --- a/.github/workflows/on_issues_ai.yml +++ b/.github/workflows/on_issues_ai.yml @@ -261,14 +261,22 @@ jobs: improvement) labels+=("enhancement") if [[ "$EXISTING_ADDON" == true ]]; then - labels+=("ai: fix-proposed" "ai: fixing") + labels+=("ai: fix-proposed") body="**Assessment:** ${summary} **Estimated risk:** ${risk} - ${response} + ${response}" + if [[ "$ISSUE_AUTHOR" == "$REPOSITORY_OWNER" ]]; then + labels+=("ai: fixing") + body="${body} - This targets an existing add-on, so repository analysis and a validated draft fix attempt will start automatically." + This targets an existing add-on, so repository analysis and a validated draft fix attempt will start automatically because the issue was opened by the repository owner." + else + body="${body} + + This targets an existing add-on. A maintainer can approve repository analysis and an automated draft fix attempt by adding the \`ai: fix-approved\` label." + fi else labels+=("ai: maintainer-review") body="${response} @@ -319,18 +327,16 @@ jobs: needs.triage.outputs.category == 'improvement' && needs.triage.outputs.existing_addon == 'true' ) || + needs.triage.outputs.category == 'bug' + ) && + ( ( - needs.triage.outputs.category == 'bug' && - ( - ( - github.event.action == 'labeled' && - github.event.label.name == 'ai: fix-approved' - ) || - ( - (github.event.action == 'opened' || github.event.action == 'reopened') && - github.event.issue.user.login == github.repository_owner - ) - ) + github.event.action == 'labeled' && + github.event.label.name == 'ai: fix-approved' + ) || + ( + (github.event.action == 'opened' || github.event.action == 'reopened') && + github.event.issue.user.login == github.repository_owner ) ) needs: [detect_submitter, triage] @@ -395,7 +401,7 @@ jobs: - name: Run Codex id: codex if: steps.prepare.outputs.existing_pr == '' - uses: openai/codex-action@v1 + uses: openai/codex-action@52fe01ec70a42f454c9d2ebd47598f9fd6893d56 # v1 with: openai-api-key: ${{ secrets.OPENAI_API_KEY }} prompt-file: codex-prompt.md @@ -652,3 +658,23 @@ jobs: gh issue edit "$ISSUE_NUMBER" --repo "$REPO" \ --add-label "ai: pr-created" gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body "$body" + + - name: Report publication failure + if: failure() && steps.validation.outcome != 'failure' + env: + GH_TOKEN: ${{ secrets.AI_PR_TOKEN || secrets.GITHUB_TOKEN }} + ISSUE_NUMBER: ${{ github.event.issue.number }} + REPO: ${{ github.repository }} + RUN_URL: https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} + run: | + set -euo pipefail + for label in "ai: fix-approved" "ai: fix-proposed" "ai: fixing"; do + gh issue edit "$ISSUE_NUMBER" --repo "$REPO" \ + --remove-label "$label" || true + done + gh issue edit "$ISSUE_NUMBER" --repo "$REPO" \ + --add-label "ai: maintainer-review" || true + gh issue comment "$ISSUE_NUMBER" --repo "$REPO" --body \ + "### Automated publication failed + + A patch was generated but could not be published (applying, pushing, or opening the draft pull request failed), so no pull request was created. A maintainer should review the [workflow run](${RUN_URL})."