diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 827e736b..2cee1a07 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -25,3 +25,5 @@ - [ ] Change is minimal and task-focused - [ ] No unrelated refactors included - [ ] No secrets or private tokens added +- [ ] Labels applied match risk level (`risk:low`, `risk:medium`, or `risk:high`) +- [ ] `agent:ready` label NOT applied until task packet is complete and authorized diff --git a/.github/agents/release-assistant.agent.md b/.github/agents/release-assistant.agent.md index 12f875fa..08ef50e2 100644 --- a/.github/agents/release-assistant.agent.md +++ b/.github/agents/release-assistant.agent.md @@ -1,7 +1,7 @@ --- name: release-assistant description: Prepare release notes, artifact checks, and rollback-ready release packets. -tools: ['read', 'search', 'edit'] +tools: ["read", "search", "edit"] --- You are the Release Steward. diff --git a/.github/workflows/agent-label-sync.yml b/.github/workflows/agent-label-sync.yml index 290e09f0..ed63f0d5 100644 --- a/.github/workflows/agent-label-sync.yml +++ b/.github/workflows/agent-label-sync.yml @@ -5,6 +5,7 @@ on: push: paths: - '.github/workflows/agent-label-sync.yml' + - '.github/ISSUE_TEMPLATE/agent_task.yml' permissions: contents: read diff --git a/.github/workflows/agent-task-queue.yml b/.github/workflows/agent-task-queue.yml index 1c8b5227..20ce0ca2 100644 --- a/.github/workflows/agent-task-queue.yml +++ b/.github/workflows/agent-task-queue.yml @@ -46,6 +46,28 @@ jobs: c.body?.includes(`- #${issue_number}:`) ); + if (existingContract && hadInProgress) { + core.info("Idempotency guard: contract already posted and agent:in-progress already set; skipping duplicate enqueue."); + if (hadReady) { + try { + await github.rest.issues.removeLabel({ + owner, + repo, + issue_number, + name: "agent:ready", + }); + } catch (removeError) { + if (removeError.status === 404) { + core.info("agent:ready was already removed."); + } else { + core.error(`Idempotency cleanup failed to remove agent:ready: ${removeError.message}`); + throw removeError; + } + } + } + return; + } + let addedInProgress = false; let removedReady = false; @@ -69,11 +91,11 @@ jobs: name: "agent:ready", }); removedReady = true; - } catch (error) { - if (error.status === 404) { + } catch (removeError) { + if (removeError.status === 404) { core.info("agent:ready was already removed."); } else { - throw error; + throw removeError; } } } @@ -104,7 +126,7 @@ jobs: body: lines.join("\n"), }); } catch (error) { - core.warning(`Queue transition failed: ${error.message}`); + core.error(`Queue transition failed: ${error.message}`); if (addedInProgress && !hadInProgress) { try { @@ -115,7 +137,7 @@ jobs: name: "agent:in-progress", }); } catch (rollbackError) { - core.warning(`Rollback remove agent:in-progress failed: ${rollbackError.message}`); + core.error(`Rollback remove agent:in-progress failed: ${rollbackError.message}`); } } @@ -128,7 +150,7 @@ jobs: labels: ["agent:ready"], }); } catch (rollbackError) { - core.warning(`Rollback add agent:ready failed: ${rollbackError.message}`); + core.error(`Rollback add agent:ready failed: ${rollbackError.message}`); } } diff --git a/.gitignore b/.gitignore index f3614305..daccb61c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ build/ # IDE .idea/ +.coverage diff --git a/AGENTS.md b/AGENTS.md index 7de2d4ab..e32fa622 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -33,4 +33,6 @@ bash scripts/verify ## Queue Trigger Warning -Applying label `agent:ready` triggers the queue workflow immediately. +> **⚠ WARNING:** Applying label `agent:ready` triggers the queue workflow **immediately and irreversibly**. +> The workflow will transition the issue to `agent:in-progress` and post an execution contract comment. +> Only apply this label when the task packet is complete and implementation is authorized. diff --git a/backend/.coverage b/backend/.coverage index 19b43725..9c7d2171 100644 Binary files a/backend/.coverage and b/backend/.coverage differ