From 3cecba3f4aa9caeaf67af6645d29903ad623bc55 Mon Sep 17 00:00:00 2001 From: openhands Date: Sun, 22 Mar 2026 07:37:26 +0000 Subject: [PATCH] fix: fix: planner-created issues lose backlog labels on creation (#535) Root cause: the gardener quality gate strips the `backlog` label from issues missing "## Acceptance criteria" checkboxes and "## Affected files" sections. The planner formula never instructed including these sections, so every planner-created issue lost its label on the next gardener run. Three changes to formulas/run-planner.toml: 1. Require issue bodies to include acceptance criteria and affected files sections (matching the issue template format the gardener quality gate enforces). 2. Add post-creation label verification via separate API call as a belt-and-suspenders defense against Codeberg silently dropping labels during issue creation. 3. Make label ID resolution unconditional in prediction-triage (was skippable when no predictions existed, starving file-at-constraints of the backlog label ID). Co-Authored-By: Claude Opus 4.6 (1M context) --- formulas/run-planner.toml | 45 ++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/formulas/run-planner.toml b/formulas/run-planner.toml index ab14325..5e1111e 100644 --- a/formulas/run-planner.toml +++ b/formulas/run-planner.toml @@ -63,7 +63,8 @@ Evidence from the preflight step informs whether each prediction is valid curl -sf -H "Authorization: token $CODEBERG_TOKEN" \ "$CODEBERG_API/issues?state=open&type=issues&labels=prediction%2Funreviewed&limit=50" - If there are none, note that and proceed to update-prerequisite-tree. + If there are none, note that and skip to step 3b (label resolution + is still required — the file-at-constraints step needs label IDs). 2. Read available formulas from $FACTORY_ROOT/formulas/*.toml so you know what actions can be dispatched. @@ -72,7 +73,9 @@ Evidence from the preflight step informs whether each prediction is valid curl -sf -H "Authorization: token $CODEBERG_TOKEN" \ "$CODEBERG_API/issues?state=open&type=issues&limit=50" -3b. Resolve label IDs needed for triage (fetch via $CODEBERG_API/labels): +3b. Resolve label IDs needed for triage AND filing (fetch via $CODEBERG_API/labels). + ALWAYS execute this step, even if there are no predictions to triage — + the file-at-constraints step depends on these IDs: - → prediction/unreviewed - → prediction/backlog - → prediction/actioned (create if missing, @@ -105,10 +108,24 @@ Evidence from the preflight step informs whether each prediction is valid 5. Executing triage decisions via API: For PROMOTE_ACTION / PROMOTE_BACKLOG: - a. Create the new issue with the 'action' or 'backlog' label: + a. Create the new issue with the 'action' or 'backlog' label. + IMPORTANT — the issue body MUST include these sections so the + gardener quality gate does not strip the backlog label: + - "## Acceptance criteria" with at least one checkbox (- [ ] ...) + - "## Affected files" with at least one file path + Example body structure: + ## Problem\n\n\n## Proposed solution\n\n\n## Affected files\n- \n- \n\n## Acceptance criteria\n- [ ] \n- [ ] CI green + Create the issue: curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \ -H "Content-Type: application/json" "$CODEBERG_API/issues" \ -d '{"title":"...","body":"...","labels":[]}' + Extract the issue number from the response (jq -r '.number'). + a2. Verify the label was applied (Codeberg may silently drop labels + on creation). Re-apply via a separate POST if missing: + curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \ + -H "Content-Type: application/json" \ + "$CODEBERG_API/issues//labels" \ + -d '{"labels":[]}' b. Comment on the prediction with "Actioned as #NNN — ": curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \ -H "Content-Type: application/json" \ @@ -274,19 +291,27 @@ Filing gate — for each constraint: 1. Check if an issue already exists for this constraint (match by issue number reference in the tree, or search open issues by title). -2. If no issue exists, create one: +2. If no issue exists, create one. + IMPORTANT — the issue body MUST include these sections so the + gardener quality gate does not strip the backlog label: + - "## Affected files" with at least one file path + - "## Acceptance criteria" with at least one checkbox (- [ ] ...) + Use this body structure: + ## Problem\n\n\n## Proposed solution\n\n\n## Affected files\n- \n- \n\n## Acceptance criteria\n- [ ] \n- [ ] CI green\n\n## Dependencies\n- #NNN (if depends on other open issues) + Create the issue: curl -sf -X POST \ -H "Authorization: token $CODEBERG_TOKEN" \ -H "Content-Type: application/json" \ "$CODEBERG_API/issues" \ -d '{"title":"...","body":"...","labels":[]}' + Extract the issue number from the response (jq -r '.number'). - Issue body should include: - - What this prerequisite is - - Which objectives it blocks (with issue numbers) - - Why it's a constraint (blocking score) - - Rough approach if known - - ## Depends on section if it depends on other open issues +2b. Verify the label was applied (Codeberg may silently drop labels + on creation). Always re-apply via a separate POST to be safe: + curl -sf -X POST -H "Authorization: token $CODEBERG_TOKEN" \ + -H "Content-Type: application/json" \ + "$CODEBERG_API/issues//labels" \ + -d '{"labels":[]}' 3. If an issue already exists and is open, skip it — no duplicate filing.