From c2a9a9d974e4bc1002b91ac1187b09828bad89f6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 01:49:15 +0000 Subject: [PATCH 1/4] Initial plan From e05974f969142352cca8a1a8c3826f0fb6b29a47 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 01:59:14 +0000 Subject: [PATCH 2/4] fix: enforce two-checkpoint pre-flight validation and add PR closure labeling - Add two-checkpoint validation strategy to AGENTS.md (Checkpoint 1 after first code edit with `make build && make fmt`, Checkpoint 2 before every report_progress call with `make agent-finish`) - Update Quick Reference and MCP sections to reference the new strategy - Add .github/workflows/label-closed-prs.yml to auto-label closed-without-merge PRs with closure reasons (closed:ci-failure, closed:reviewer-rejected, closed:duplicate, closed:unknown) Closes #N/A (issue from copilot-opt analysis)" Agent-Logs-Url: https://github.com/github/gh-aw/sessions/fe70b7dc-b4e6-4934-a55a-5593724a09da Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com> --- .github/workflows/label-closed-prs.yml | 129 +++++++++++++++++++++++++ AGENTS.md | 38 ++++++-- 2 files changed, 159 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/label-closed-prs.yml diff --git a/.github/workflows/label-closed-prs.yml b/.github/workflows/label-closed-prs.yml new file mode 100644 index 00000000000..f7490cd5e98 --- /dev/null +++ b/.github/workflows/label-closed-prs.yml @@ -0,0 +1,129 @@ +name: Label Closed PRs + +# Trigger when a pull request is closed (either merged or without merging) +on: + pull_request: + types: [closed] + +permissions: + pull-requests: write + checks: read + +jobs: + label-closure-reason: + name: Label PR Closure Reason + runs-on: ubuntu-latest + # Only label PRs that were closed WITHOUT merging + if: github.event.pull_request.merged == false + steps: + - name: Determine and apply closure reason label + uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9 + with: + script: | + const { owner, repo } = context.repo; + const prNumber = context.payload.pull_request.number; + + core.info('================================================='); + core.info('Label Closed PRs — Closure Reason Classifier'); + core.info('================================================='); + core.info(`PR #${prNumber} closed without merging`); + + // Determine closure reason by inspecting CI checks and review state + async function getClosureReason() { + // 1. Check the combined CI status for the PR head commit + const headSha = context.payload.pull_request.head.sha; + + let ciFailure = false; + try { + // Fetch check runs for the head commit + const checkRunsResp = await github.rest.checks.listForRef({ + owner, + repo, + ref: headSha, + per_page: 100, + }); + + const runs = checkRunsResp.data.check_runs; + const failed = runs.filter( + r => r.conclusion === 'failure' || r.conclusion === 'timed_out' + ); + if (failed.length > 0) { + ciFailure = true; + core.info(`CI failure detected: ${failed.map(r => r.name).join(', ')}`); + } + } catch (err) { + core.warning(`Could not fetch check runs: ${err.message}`); + } + + if (ciFailure) { + return 'closed:ci-failure'; + } + + // 2. Check if a reviewer explicitly requested changes or left a closing comment + let reviewerRejected = false; + try { + const reviewsResp = await github.rest.pulls.listReviews({ + owner, + repo, + pull_number: prNumber, + }); + + const changesRequested = reviewsResp.data.some( + r => r.state === 'CHANGES_REQUESTED' + ); + if (changesRequested) { + reviewerRejected = true; + core.info('Reviewer requested changes before PR was closed'); + } + } catch (err) { + core.warning(`Could not fetch reviews: ${err.message}`); + } + + if (reviewerRejected) { + return 'closed:reviewer-rejected'; + } + + // 3. Check for a duplicate/superseded label already applied + const existingLabels = context.payload.pull_request.labels.map(l => l.name); + if (existingLabels.some(l => l.includes('duplicate') || l.includes('superseded'))) { + return 'closed:duplicate'; + } + + // 4. Fall back to unknown + return 'closed:unknown'; + } + + const label = await getClosureReason(); + core.info(`Applying label: ${label}`); + + // Ensure the label exists (create it if missing) + const labelColors = { + 'closed:ci-failure': 'e11d48', // red + 'closed:reviewer-rejected': 'f97316', // orange + 'closed:duplicate': '8b5cf6', // purple + 'closed:unknown': '94a3b8', // gray + }; + + try { + await github.rest.issues.getLabel({ owner, repo, name: label }); + } catch { + // Label doesn't exist yet — create it + await github.rest.issues.createLabel({ + owner, + repo, + name: label, + color: labelColors[label] || '94a3b8', + description: `PR was closed without merging: ${label.replace('closed:', '')}`, + }); + core.info(`Created label: ${label}`); + } + + // Apply the label to the PR + await github.rest.issues.addLabels({ + owner, + repo, + issue_number: prNumber, + labels: [label], + }); + + core.info(`✅ Applied label '${label}' to PR #${prNumber}`); diff --git a/AGENTS.md b/AGENTS.md index 1f50b421d76..2cb54b7fb15 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,17 +48,35 @@ Use the **report_progress** tool to commit and push your changes. This will auto ### ⚠️ MANDATORY PRE-COMMIT VALIDATION ⚠️ -**🚨 BEFORE EVERY COMMIT - NO EXCEPTIONS:** +**🚨 TWO-CHECKPOINT VALIDATION STRATEGY — NO EXCEPTIONS:** + +#### Checkpoint 1 — After First Significant Code Edit + +Run this immediately after making your first substantial code change (do NOT wait until the end): + +```bash +make build && make fmt # Catch compile errors and formatting issues early +``` + +**Why checkpoint 1 matters:** +- Surfaces compile errors before you spend more context on subsequent edits +- Prevents wasted work if the approach is fundamentally broken +- Cheap to run (~2s) and gives immediate feedback + +#### Checkpoint 2 — Before Every `report_progress` / PR Creation + +**🚨 DO NOT call `report_progress` (which creates/updates the PR) until this passes:** ```bash make agent-finish # Runs build, test, recompile, fmt, lint ``` -**Why this matters:** +**Why checkpoint 2 matters:** - **CI WILL FAIL** if you skip this step - this is automatic and non-negotiable - Unformatted code causes immediate CI failures that block all other work - This has caused **5 CI failures in a single day** - don't be the 6th! - The formatting check (`go fmt`) is strict and cannot be disabled +- PRs that fail CI immediately after opening are closed without merging — a wasted session **If you're in a hurry** and `make agent-finish` takes too long, **at minimum run**: ```bash @@ -1138,7 +1156,7 @@ Use the mcpscripts-make tool with args: "build" ← may fail with context ca Use the mcpscripts-go tool with args: "test ./..." ← may fail with context canceled ``` -**Additional rule**: Add an **intermediate validation checkpoint** using bash after the first major code edit (e.g., `make build`), not just at the very end of the session. This surfaces compile errors early, before the agent spends more context on subsequent edits. +**Additional rule**: Follow the **two-checkpoint validation strategy** (see Critical Requirements): run `make build && make fmt` after the first major code edit (Checkpoint 1), and run `make agent-finish` before every `report_progress` call (Checkpoint 2). Both checkpoints must use direct `bash` commands, not MCP tools. **When `mcpscripts-*` tools are safe to use:** - Early in a session, before any long exploration phase @@ -1208,13 +1226,17 @@ make minor-release # Automated via GitHub Actions Use **report_progress** to commit, push, and update the PR. Never leave changes uncommitted. -### 🚨 CRITICAL - Pre-Commit Checklist -Before EVERY commit: -1. ✅ Run `make agent-finish` (or at minimum `make fmt`) +### 🚨 CRITICAL - Two-Checkpoint Validation (Pre-Commit + Pre-PR) +**Checkpoint 1** — After first significant code edit: +1. ✅ Run `make build && make fmt` (fast early feedback, ~2s) +2. ✅ Fix any compile errors or formatting issues before proceeding + +**Checkpoint 2** — Before every `report_progress` call (creates/updates PR): +1. ✅ Run `make agent-finish` (or at minimum `make fmt && make test-unit`) 2. ✅ Verify no errors from the above command -3. ✅ Only then commit and push +3. ✅ Only then call `report_progress` -**This is NOT optional** - skipping this causes immediate CI failures. +**This is NOT optional** — PRs that fail CI immediately after opening are closed without merging, wasting the entire agent session. ### Development Guidelines - Go project with Makefile-managed build/test/lint From fdb9fc0cca8c2762cae39cb9aefdbba75a334701 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 02:23:25 +0000 Subject: [PATCH 3/4] feat: add make agent_report_progress lightweight pre-PR validation gate Add a new Makefile target `agent_report_progress` that runs build + fmt + test-unit in under 30 seconds. This is the dedicated fast gate to run before every `report_progress` / create_pull_request call, replacing the ad-hoc `make fmt && make test-unit` guidance. - Makefile: add `agent_report_progress` target (build + fmt + test-unit) and update help text - AGENTS.md: update Checkpoint 2, Quick Reference, and MCP section to reference the new target; demote `make agent-finish` to "when more time is available" Agent-Logs-Url: https://github.com/github/gh-aw/sessions/0b025a4a-8c95-4c6e-add1-d90b485db64d Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- AGENTS.md | 17 +++++++++++------ Makefile | 11 ++++++++++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 2cb54b7fb15..57dc69f02e1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -68,7 +68,13 @@ make build && make fmt # Catch compile errors and formatting issues early **🚨 DO NOT call `report_progress` (which creates/updates the PR) until this passes:** ```bash -make agent-finish # Runs build, test, recompile, fmt, lint +make agent_report_progress # build + fmt + test-unit (<30s) — fast pre-PR gate +``` + +When more time is available, prefer the full suite: + +```bash +make agent-finish # Runs build, test, recompile, fmt, lint (full validation) ``` **Why checkpoint 2 matters:** @@ -78,10 +84,9 @@ make agent-finish # Runs build, test, recompile, fmt, lint - The formatting check (`go fmt`) is strict and cannot be disabled - PRs that fail CI immediately after opening are closed without merging — a wasted session -**If you're in a hurry** and `make agent-finish` takes too long, **at minimum run**: +**If you're in a hurry** and `make agent-finish` takes too long, use the dedicated fast gate: ```bash -make fmt # Format Go, JavaScript, and JSON files -make test-unit # Fast unit tests (~25s) +make agent_report_progress # build + fmt + test-unit (~30s) ``` **After making Go code changes (*.go files):** @@ -1156,7 +1161,7 @@ Use the mcpscripts-make tool with args: "build" ← may fail with context ca Use the mcpscripts-go tool with args: "test ./..." ← may fail with context canceled ``` -**Additional rule**: Follow the **two-checkpoint validation strategy** (see Critical Requirements): run `make build && make fmt` after the first major code edit (Checkpoint 1), and run `make agent-finish` before every `report_progress` call (Checkpoint 2). Both checkpoints must use direct `bash` commands, not MCP tools. +**Additional rule**: Follow the **two-checkpoint validation strategy** (see Critical Requirements): run `make build && make fmt` after the first major code edit (Checkpoint 1), and run `make agent_report_progress` before every `report_progress` call (Checkpoint 2). Both checkpoints must use direct `bash` commands, not MCP tools. **When `mcpscripts-*` tools are safe to use:** - Early in a session, before any long exploration phase @@ -1232,7 +1237,7 @@ Use **report_progress** to commit, push, and update the PR. Never leave changes 2. ✅ Fix any compile errors or formatting issues before proceeding **Checkpoint 2** — Before every `report_progress` call (creates/updates PR): -1. ✅ Run `make agent-finish` (or at minimum `make fmt && make test-unit`) +1. ✅ Run `make agent_report_progress` (build + fmt + test-unit, <30s) 2. ✅ Verify no errors from the above command 3. ✅ Only then call `report_progress` diff --git a/Makefile b/Makefile index bb92e1d5b47..39f03f6efc7 100644 --- a/Makefile +++ b/Makefile @@ -750,6 +750,14 @@ sbom: agent-finish: deps-dev fmt lint build build-wasm test-all fix recompile dependabot generate-schema-docs generate-agent-factory security-scan @echo "Agent finished tasks successfully." +# Lightweight pre-PR gate — run before every report_progress / create_pull_request call. +# Targets < 30 seconds: build (~2s) + fmt (~1s) + test-unit (~25s). +# This catches compile errors, formatting violations, and common unit-test regressions +# before the PR is opened, without waiting for the full agent-finish suite. +.PHONY: agent_report_progress +agent_report_progress: build fmt test-unit + @echo "Pre-PR validation passed. Safe to call report_progress." + # Help target .PHONY: help help: @@ -822,6 +830,7 @@ help: @echo " preview-docs - Preview built documentation with Astro" @echo " clean-docs - Clean documentation artifacts (dist, node_modules, .astro)" - @echo " agent-finish - Complete validation sequence (build, test, fix, recompile, fmt, lint, security-scan)" + @echo " agent-finish - Complete validation sequence (build, test, fix, recompile, fmt, lint, security-scan)" + @echo " agent_report_progress - Lightweight pre-PR gate: build + fmt + test-unit (<30s)" @echo " sbom - Generate SBOM in SPDX and CycloneDX formats (requires syft)" @echo " help - Show this help message" From eb81b41fceba66ef2bcdcddd5cd2995e7d8cfb62 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 5 May 2026 03:01:31 +0000 Subject: [PATCH 4/4] =?UTF-8?q?fix:=20address=20reviewer=20feedback=20?= =?UTF-8?q?=E2=80=94=20issues:write=20perm,=20404-only=20label=20create,?= =?UTF-8?q?=20hyphenated=20target,=20heading=20update?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Agent-Logs-Url: https://github.com/github/gh-aw/sessions/a403aac6-96c4-462b-bb83-a69909721d32 Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/label-closed-prs.yml | 6 +++++- AGENTS.md | 10 +++++----- Makefile | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/label-closed-prs.yml b/.github/workflows/label-closed-prs.yml index f7490cd5e98..dd7031ab621 100644 --- a/.github/workflows/label-closed-prs.yml +++ b/.github/workflows/label-closed-prs.yml @@ -7,6 +7,7 @@ on: permissions: pull-requests: write + issues: write checks: read jobs: @@ -106,7 +107,10 @@ jobs: try { await github.rest.issues.getLabel({ owner, repo, name: label }); - } catch { + } catch (err) { + if (err.status !== 404) { + throw err; + } // Label doesn't exist yet — create it await github.rest.issues.createLabel({ owner, diff --git a/AGENTS.md b/AGENTS.md index 57dc69f02e1..29c1b16797f 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -46,7 +46,7 @@ Use the **report_progress** tool to commit and push your changes. This will auto **Never leave file changes uncommitted.** Even for small or "obvious" changes, always use **report_progress** to push your work to a PR so it can be reviewed. -### ⚠️ MANDATORY PRE-COMMIT VALIDATION ⚠️ +### ⚠️ MANDATORY PRE-COMMIT AND PRE-PR VALIDATION ⚠️ **🚨 TWO-CHECKPOINT VALIDATION STRATEGY — NO EXCEPTIONS:** @@ -68,7 +68,7 @@ make build && make fmt # Catch compile errors and formatting issues early **🚨 DO NOT call `report_progress` (which creates/updates the PR) until this passes:** ```bash -make agent_report_progress # build + fmt + test-unit (<30s) — fast pre-PR gate +make agent-report-progress # build + fmt + test-unit (<30s) — fast pre-PR gate ``` When more time is available, prefer the full suite: @@ -86,7 +86,7 @@ make agent-finish # Runs build, test, recompile, fmt, lint (full validation) **If you're in a hurry** and `make agent-finish` takes too long, use the dedicated fast gate: ```bash -make agent_report_progress # build + fmt + test-unit (~30s) +make agent-report-progress # build + fmt + test-unit (~30s) ``` **After making Go code changes (*.go files):** @@ -1161,7 +1161,7 @@ Use the mcpscripts-make tool with args: "build" ← may fail with context ca Use the mcpscripts-go tool with args: "test ./..." ← may fail with context canceled ``` -**Additional rule**: Follow the **two-checkpoint validation strategy** (see Critical Requirements): run `make build && make fmt` after the first major code edit (Checkpoint 1), and run `make agent_report_progress` before every `report_progress` call (Checkpoint 2). Both checkpoints must use direct `bash` commands, not MCP tools. +**Additional rule**: Follow the **two-checkpoint validation strategy** (see Critical Requirements): run `make build && make fmt` after the first major code edit (Checkpoint 1), and run `make agent-report-progress` before every `report_progress` call (Checkpoint 2). Both checkpoints must use direct `bash` commands, not MCP tools. **When `mcpscripts-*` tools are safe to use:** - Early in a session, before any long exploration phase @@ -1237,7 +1237,7 @@ Use **report_progress** to commit, push, and update the PR. Never leave changes 2. ✅ Fix any compile errors or formatting issues before proceeding **Checkpoint 2** — Before every `report_progress` call (creates/updates PR): -1. ✅ Run `make agent_report_progress` (build + fmt + test-unit, <30s) +1. ✅ Run `make agent-report-progress` (build + fmt + test-unit, <30s) 2. ✅ Verify no errors from the above command 3. ✅ Only then call `report_progress` diff --git a/Makefile b/Makefile index 39f03f6efc7..c734b053ab1 100644 --- a/Makefile +++ b/Makefile @@ -754,8 +754,8 @@ agent-finish: deps-dev fmt lint build build-wasm test-all fix recompile dependab # Targets < 30 seconds: build (~2s) + fmt (~1s) + test-unit (~25s). # This catches compile errors, formatting violations, and common unit-test regressions # before the PR is opened, without waiting for the full agent-finish suite. -.PHONY: agent_report_progress -agent_report_progress: build fmt test-unit +.PHONY: agent-report-progress +agent-report-progress: build fmt test-unit @echo "Pre-PR validation passed. Safe to call report_progress." # Help target @@ -831,6 +831,6 @@ help: @echo " clean-docs - Clean documentation artifacts (dist, node_modules, .astro)" @echo " agent-finish - Complete validation sequence (build, test, fix, recompile, fmt, lint, security-scan)" - @echo " agent_report_progress - Lightweight pre-PR gate: build + fmt + test-unit (<30s)" + @echo " agent-report-progress - Lightweight pre-PR gate: build + fmt + test-unit (<30s)" @echo " sbom - Generate SBOM in SPDX and CycloneDX formats (requires syft)" @echo " help - Show this help message"