From 12d25ced71bd6a4015dd93f8f67cadfe46e03490 Mon Sep 17 00:00:00 2001 From: Hector Martinez Date: Mon, 6 Jul 2026 09:09:56 +0200 Subject: [PATCH] feat(triage): add not-planned action to close out-of-scope issues The triage schema now accepts action: "not-planned" to close issues as out-of-scope, invalid, or spam. The post-script applies the not-planned label, posts the agent's comment, and closes the issue with reason "not planned" (matching the existing duplicate flow). This addresses feedback from konflux-ci/mobster onboarding: without not-planned, the agent must use insufficient (keeps issue open) or sufficient (may promote to coder) for issues that should be closed. Changes: - triage-result.schema.json: add not-planned to action enum - post-triage.sh: add not-planned case that labels and closes issue - post-triage.sh: add not-planned to CONTROL_LABELS array - post-triage-test.sh: add 6 tests for not-planned action - agents/triage.md: document when to use not-planned vs other actions - docs/agents/triage.md: add not-planned to control labels table All tests pass. Closes #2205 Co-Authored-By: Claude Sonnet 4.5 Signed-off-by: Hector Martinez --- .../scaffold/fullsend-repo/agents/triage.md | 23 +++++++++++++++++ .../schemas/triage-result.schema.json | 2 +- .../fullsend-repo/scripts/post-triage-test.sh | 25 +++++++++++++++++++ .../fullsend-repo/scripts/post-triage.sh | 15 ++++++++++- .../scripts/validate-output-schema-test.sh | 4 +++ 5 files changed, 67 insertions(+), 2 deletions(-) diff --git a/internal/scaffold/fullsend-repo/agents/triage.md b/internal/scaffold/fullsend-repo/agents/triage.md index 58cc303e0..868b860c2 100644 --- a/internal/scaffold/fullsend-repo/agents/triage.md +++ b/internal/scaffold/fullsend-repo/agents/triage.md @@ -173,6 +173,29 @@ When you identify a question, attempt to answer it using the repository context } ``` +### Action: `not-planned` + +The issue is out-of-scope, invalid, spam, or should otherwise not be worked on. This action closes the issue with reason `not planned`. + +Use this action for: +- Issues explicitly out of project scope (e.g., feature requests incompatible with project goals) +- Invalid reports (e.g., user error, misconfiguration, or misunderstanding) +- Spam or low-quality submissions +- Issues that would introduce technical direction counter to documented architectural decisions + +**Do NOT use this action for:** +- Issues that lack information (use `insufficient` instead) +- Issues that are duplicates of existing ones (use `duplicate` instead) +- Issues blocked on other work (use `prerequisites` instead) + +```json +{ + "action": "not-planned", + "reasoning": "Brief explanation of why this issue is being closed as not planned", + "comment": "A professional comment explaining why the issue is out of scope or invalid. Be respectful — the reporter may not have understood project boundaries. Link to relevant documentation or related discussions when applicable." +} +``` + ### Action: `insufficient` Information is missing that would change the triage outcome. Ask ONE focused, specific clarifying question. diff --git a/internal/scaffold/fullsend-repo/schemas/triage-result.schema.json b/internal/scaffold/fullsend-repo/schemas/triage-result.schema.json index 73616cab7..1ebdd9e2a 100644 --- a/internal/scaffold/fullsend-repo/schemas/triage-result.schema.json +++ b/internal/scaffold/fullsend-repo/schemas/triage-result.schema.json @@ -9,7 +9,7 @@ "properties": { "action": { "type": "string", - "enum": ["insufficient", "duplicate", "sufficient", "prerequisites", "question"] + "enum": ["insufficient", "duplicate", "sufficient", "prerequisites", "question", "not-planned"] }, "reasoning": { "type": "string", diff --git a/internal/scaffold/fullsend-repo/scripts/post-triage-test.sh b/internal/scaffold/fullsend-repo/scripts/post-triage-test.sh index fd4f4d8f4..baf077994 100755 --- a/internal/scaffold/fullsend-repo/scripts/post-triage-test.sh +++ b/internal/scaffold/fullsend-repo/scripts/post-triage-test.sh @@ -279,6 +279,31 @@ run_test "question-missing-comment-fails" \ "" \ "true" +run_test "not-planned-posts-comment" \ + '{"action":"not-planned","reasoning":"out of scope","comment":"This request is out of scope for the project goals. See docs/scope.md for more details."}' \ + "gh issue comment 42 --repo test-org/test-repo --body-file -" + +run_test "not-planned-applies-label" \ + '{"action":"not-planned","reasoning":"out of scope","comment":"This request is out of scope for the project goals."}' \ + "gh api repos/test-org/test-repo/issues/42/labels -f labels[]=not-planned --silent" + +run_test "not-planned-removes-blocked-label" \ + '{"action":"not-planned","reasoning":"out of scope","comment":"This request is out of scope."}' \ + "gh api repos/test-org/test-repo/issues/42/labels/blocked -X DELETE --silent" + +run_test "not-planned-removes-needs-info-label" \ + '{"action":"not-planned","reasoning":"out of scope","comment":"This request is out of scope."}' \ + "gh api repos/test-org/test-repo/issues/42/labels/needs-info -X DELETE --silent" + +run_test "not-planned-closes-issue" \ + '{"action":"not-planned","reasoning":"out of scope","comment":"This request is out of scope for the project goals."}' \ + "gh issue close 42 --repo test-org/test-repo --reason not planned" + +run_test "not-planned-missing-comment-fails" \ + '{"action":"not-planned","reasoning":"out of scope"}' \ + "" \ + "true" + run_test_stdout "question-control-label-refused" \ '{"action":"question","reasoning":"issue is asking a question","comment":"Answer here.","label_actions":{"reason":"Tried to set question label.","actions":[{"action":"add","label":"question"}]}}' \ "::warning::Refused to add control label 'question' -- control labels are managed by the triage pipeline" diff --git a/internal/scaffold/fullsend-repo/scripts/post-triage.sh b/internal/scaffold/fullsend-repo/scripts/post-triage.sh index 94cedb01b..9e1d39663 100755 --- a/internal/scaffold/fullsend-repo/scripts/post-triage.sh +++ b/internal/scaffold/fullsend-repo/scripts/post-triage.sh @@ -292,6 +292,15 @@ ${FAILED_CREATES}" add_label "question" ;; + not-planned) + if [[ -z "${COMMENT}" ]]; then + echo "ERROR: action is 'not-planned' but no comment provided" >&2 + exit 1 + fi + remove_label "blocked" + remove_label "needs-info" + ;; + *) echo "ERROR: unknown action '${ACTION}' — this may be a newer action that post-triage.sh does not handle yet" >&2 exit 1 @@ -384,10 +393,14 @@ else printf '%s' "${COMMENT}" | gh issue comment "${ISSUE_NUMBER}" --repo "${REPO}" --body-file - fi -# --- Post-action: close duplicate issues --- +# --- Post-action: close issues --- if [[ "${ACTION}" == "duplicate" ]]; then gh issue close "${ISSUE_NUMBER}" --repo "${REPO}" --reason "duplicate" fi +if [[ "${ACTION}" == "not-planned" ]]; then + gh issue close "${ISSUE_NUMBER}" --repo "${REPO}" --reason "not planned" +fi + echo "Post-triage complete." diff --git a/internal/scaffold/fullsend-repo/scripts/validate-output-schema-test.sh b/internal/scaffold/fullsend-repo/scripts/validate-output-schema-test.sh index 44bd813ac..f9ec03aa8 100755 --- a/internal/scaffold/fullsend-repo/scripts/validate-output-schema-test.sh +++ b/internal/scaffold/fullsend-repo/scripts/validate-output-schema-test.sh @@ -70,6 +70,10 @@ run_test "valid-question" \ '{"action":"question","reasoning":"this is a support question","comment":"Based on the docs, Python 4 is not supported. Would you like to open a feature request?"}' \ "true" +run_test "valid-not-planned" \ + '{"action":"not-planned","reasoning":"out of scope","comment":"This is out of scope."}' \ + "true" + run_test "valid-prerequisites-existing" \ '{"action":"prerequisites","reasoning":"upstream dependency","prerequisites":{"existing":[{"url":"https://github.com/org/repo/issues/99"}],"create":[]},"comment":"Blocked on upstream."}' \ "true"