Skip to content

feat(incidents): add set-status command with bulk dismiss support - #38

Merged
matthyx merged 7 commits into
mainfrom
feat/incidents-set-status
Jun 23, 2026
Merged

matthyx merged 7 commits into
mainfrom
feat/incidents-set-status

Conversation

@slashben

Copy link
Copy Markdown
Member

No description provided.

Copilot AI review requested due to automatic review settings June 22, 2026 16:46
@slashben slashben added the ai-assisted Created through Armosec AI tooling (armosec-shared-rules plugin) label Jun 22, 2026
@coderabbitai

coderabbitai Bot commented Jun 22, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: d2063942-682a-41fe-9b44-d15c84018123

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces armoctl incidents set-status, a new CLI command for changing the status of one or more runtime incidents. A shared helper runStatusChange in changestatus.go centralizes POST request construction, safety/dry-run wrapping, response parsing, and audit logging. The existing resolve command is refactored from inline logic into a thin alias that calls this shared helper with status="Resolved". The new SetStatusCmd adds incident selection via positional GUIDs, --stdin, repeatable --filter key=value pairs, and --search text, with status canonicalization via normalizeStatus. The command is registered under the top-level incidents command. Skill metadata and cheatsheet entries are updated to include the Dismissed status, and a feature documentation page plus design spec and implementation plan documents are added.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐇 A rabbit hops through incident queues,
With set-status flags and GUID stews,
--stdin pipes and --filter keys,
Dismissing troubles with the greatest ease,
runStatusChange shared by all who call,
One helper to resolve them all! 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.11% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description is minimal and contains only a metadata comment, which is insufficient to convey meaningful information about the changeset. Provide a brief description of the feature, its purpose, and key changes to help reviewers understand the pull request scope and intent.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main feature: adding a set-status command with bulk dismiss support, which is exactly what the changeset implements.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/incidents-set-status

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@slashben slashben added the release Trigger release on merge label Jun 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@cmd/incidents/setstatus_test.go`:
- Line 117: The json.Unmarshal call in the test is ignoring its error return
value, which can hide unmarshaling failures and lead to subsequent assertions
operating on zero values. Check the error returned by
json.Unmarshal(stdout.Bytes(), &got) and properly handle it by failing the test
if unmarshaling fails, ensuring that any JSON parsing issues are caught and
reported rather than silently masked.
- Line 91: The json.Unmarshal call in this test is ignoring the error return
value by assigning it to underscore, which can mask test failures. Capture the
error return value from json.Unmarshal when unmarshaling stdout.Bytes() into the
got variable, and add a check to fail the test immediately if an error occurs
(using t.Fatalf or t.Errorf with an appropriate error message). This ensures
that any unmarshaling failures are caught and reported rather than silently
proceeding with zero values.
- Line 150: The error returned by the Decode method of json.NewDecoder is being
ignored using the blank identifier in the line with
json.NewDecoder(r.Body).Decode(&body). Instead of ignoring this error with an
underscore, capture the error return value and check if it is not nil, then
handle it appropriately (such as failing the test or logging an error). This
ensures that JSON parsing failures are detected and don't cause misleading test
assertions operating on zero values.

In `@docs/features/incidents-set-status.md`:
- Line 24: The documentation sentence about required selection methods is
incomplete and excludes `--stdin` as a valid option for supplying GUIDs. Update
the sentence in the incidents-set-status.md file to include `--stdin` alongside
GUIDs, `--filter`, and `--search` as valid standalone methods for specifying
incidents. This reflects the actual behavior in cmd/incidents/setstatus.go where
stdin GUIDs are merged into the selection set before validation occurs.

In `@docs/superpowers/plans/2026-06-22-incidents-set-status.md`:
- Around line 680-682: Add language tags to all fenced code blocks in the
markdown file to comply with the MD040 linting rule. The code fence at lines
680-682 containing the armoctl incidents set-status command example should be
labeled with the bash tag since it represents a command-line interface command.
Apply the same fix to all other unlabeled fenced code blocks referenced in the
comment (lines 696-706 and 715-717), using appropriate language tags (bash for
CLI commands, text for plain text examples, markdown for markdown examples)
based on the content of each block.

In `@docs/superpowers/specs/2026-06-22-incidents-set-status-design.md`:
- Around line 44-47: Add language tags to all fenced code blocks in the markdown
spec to comply with markdownlint rule MD040. For the command examples in the
fenced blocks at lines 44-47, 66-72, and 104-112, add the appropriate language
identifier (bash for CLI commands, text for plain text examples, json for JSON
examples) immediately after the opening backticks of each code fence. This will
ensure the spec passes linting checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e2971458-9643-4aa2-bb4b-4319e46d0bc8

📥 Commits

Reviewing files that changed from the base of the PR and between 5b5148d and 5489585.

📒 Files selected for processing (11)
  • cmd/incidents/changestatus.go
  • cmd/incidents/changestatus_test.go
  • cmd/incidents/incidents.go
  • cmd/incidents/resolve.go
  • cmd/incidents/setstatus.go
  • cmd/incidents/setstatus_test.go
  • cmd/incidents/skill.go
  • cmd/incidents/types.go
  • docs/features/incidents-set-status.md
  • docs/superpowers/plans/2026-06-22-incidents-set-status.md
  • docs/superpowers/specs/2026-06-22-incidents-set-status-design.md

Comment thread cmd/incidents/setstatus_test.go Outdated
t.Fatal(err)
}
var got map[string]any
_ = json.Unmarshal(stdout.Bytes(), &got)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Check the error from json.Unmarshal.

Ignoring the unmarshal error could mask test failures. If unmarshaling fails, subsequent type assertions will silently use zero values, potentially causing confusing or misleading test failures.

🛡️ Proposed fix
 var got map[string]any
-_ = json.Unmarshal(stdout.Bytes(), &got)
+if err := json.Unmarshal(stdout.Bytes(), &got); err != nil {
+	t.Fatalf("failed to unmarshal output: %v", err)
+}
 req, _ := got["request"].(map[string]any)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_ = json.Unmarshal(stdout.Bytes(), &got)
var got map[string]any
if err := json.Unmarshal(stdout.Bytes(), &got); err != nil {
t.Fatalf("failed to unmarshal output: %v", err)
}
req, _ := got["request"].(map[string]any)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/incidents/setstatus_test.go` at line 91, The json.Unmarshal call in this
test is ignoring the error return value by assigning it to underscore, which can
mask test failures. Capture the error return value from json.Unmarshal when
unmarshaling stdout.Bytes() into the got variable, and add a check to fail the
test immediately if an error occurs (using t.Fatalf or t.Errorf with an
appropriate error message). This ensures that any unmarshaling failures are
caught and reported rather than silently proceeding with zero values.

Comment thread cmd/incidents/setstatus_test.go Outdated
t.Fatal(err)
}
var got map[string]any
_ = json.Unmarshal(stdout.Bytes(), &got)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Check the error from json.Unmarshal.

Ignoring the unmarshal error could mask test failures. If unmarshaling fails, the subsequent type assertions and checks will operate on zero values, potentially causing confusing test failures.

🛡️ Proposed fix
 var got map[string]any
-_ = json.Unmarshal(stdout.Bytes(), &got)
+if err := json.Unmarshal(stdout.Bytes(), &got); err != nil {
+	t.Fatalf("failed to unmarshal output: %v", err)
+}
 req, _ := got["request"].(map[string]any)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_ = json.Unmarshal(stdout.Bytes(), &got)
var got map[string]any
if err := json.Unmarshal(stdout.Bytes(), &got); err != nil {
t.Fatalf("failed to unmarshal output: %v", err)
}
req, _ := got["request"].(map[string]any)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/incidents/setstatus_test.go` at line 117, The json.Unmarshal call in the
test is ignoring its error return value, which can hide unmarshaling failures
and lead to subsequent assertions operating on zero values. Check the error
returned by json.Unmarshal(stdout.Bytes(), &got) and properly handle it by
failing the test if unmarshaling fails, ensuring that any JSON parsing issues
are caught and reported rather than silently masked.

Comment thread cmd/incidents/setstatus_test.go Outdated
t.Errorf("path: %s", r.URL.Path)
}
var body map[string]any
_ = json.NewDecoder(r.Body).Decode(&body)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Check the error from json.NewDecoder.Decode.

Ignoring the decode error could mask issues with the request body format. If the body is not valid JSON or doesn't decode properly, the subsequent assertions will operate on zero values, potentially causing misleading test results.

🛡️ Proposed fix
 var body map[string]any
-_ = json.NewDecoder(r.Body).Decode(&body)
+if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
+	t.Errorf("failed to decode request body: %v", err)
+	w.WriteHeader(400)
+	return
+}
 if body["status"] != "Dismissed" {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
_ = json.NewDecoder(r.Body).Decode(&body)
var body map[string]any
if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
t.Errorf("failed to decode request body: %v", err)
w.WriteHeader(400)
return
}
if body["status"] != "Dismissed" {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cmd/incidents/setstatus_test.go` at line 150, The error returned by the
Decode method of json.NewDecoder is being ignored using the blank identifier in
the line with json.NewDecoder(r.Body).Decode(&body). Instead of ignoring this
error with an underscore, capture the error return value and check if it is not
nil, then handle it appropriately (such as failing the test or logging an
error). This ensures that JSON parsing failures are detected and don't cause
misleading test assertions operating on zero values.

Comment thread docs/features/incidents-set-status.md Outdated
| `--dry-run` | Preview the request without sending it. |
| `--yes` | Confirm the mutation in non-interactive mode. |

At least one of GUIDs, `--filter`, or `--search` is required.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Clarify the selection requirement.

The current sentence omits --stdin, which is also a valid standalone way to supply GUIDs. Tightening this wording will avoid telling users that piped bulk-dismiss flows are unsupported.

As per the cmd/incidents/setstatus.go:15-63 snippet, stdin GUIDs are merged into the selection set before validation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/features/incidents-set-status.md` at line 24, The documentation sentence
about required selection methods is incomplete and excludes `--stdin` as a valid
option for supplying GUIDs. Update the sentence in the incidents-set-status.md
file to include `--stdin` alongside GUIDs, `--filter`, and `--search` as valid
standalone methods for specifying incidents. This reflects the actual behavior
in cmd/incidents/setstatus.go where stdin GUIDs are merged into the selection
set before validation occurs.

Comment on lines +680 to +682
```
armoctl incidents set-status [guid...] --status <Open|Investigating|Dismissed|Resolved> [flags]
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language tags to the fenced examples.

Markdownlint already flags the unlabeled fences in this plan (MD040). Label them text/bash/markdown as appropriate so the plan stays lint-clean.

Also applies to: 696-706, 715-717

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 682-682: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/plans/2026-06-22-incidents-set-status.md` around lines 680 -
682, Add language tags to all fenced code blocks in the markdown file to comply
with the MD040 linting rule. The code fence at lines 680-682 containing the
armoctl incidents set-status command example should be labeled with the bash tag
since it represents a command-line interface command. Apply the same fix to all
other unlabeled fenced code blocks referenced in the comment (lines 696-706 and
715-717), using appropriate language tags (bash for CLI commands, text for plain
text examples, markdown for markdown examples) based on the content of each
block.

Source: Linters/SAST tools

Comment on lines +44 to +47
```
armoctl incidents set-status [guid...] --status <Open|Investigating|Dismissed|Resolved> [flags]
armoctl incidents resolve <guid> [--false-positive] # unchanged; now an alias
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add language tags to the fenced examples.

Markdownlint already flags the unlabeled fences in this doc (MD040). Label them text/bash/json as appropriate so the spec stays lint-clean.

Also applies to: 66-72, 104-112

🧰 Tools
🪛 markdownlint-cli2 (0.22.1)

[warning] 44-44: Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/superpowers/specs/2026-06-22-incidents-set-status-design.md` around
lines 44 - 47, Add language tags to all fenced code blocks in the markdown spec
to comply with markdownlint rule MD040. For the command examples in the fenced
blocks at lines 44-47, 66-72, and 104-112, add the appropriate language
identifier (bash for CLI commands, text for plain text examples, json for JSON
examples) immediately after the opening backticks of each code fence. This will
ensure the spec passes linting checks.

Source: Linters/SAST tools

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new armoctl incidents set-status CLI command to change incident status to any backend-supported state (including bulk dismiss), while refactoring the existing resolve command to reuse a shared change-status helper and preserving current resolve behavior.

Changes:

  • Introduces shared runStatusChange helper (request building + safety.Wrap mutation contract) and refactors resolve to call it.
  • Adds set-status command supporting bulk selection via positional GUIDs, --stdin, --filter, and --search (query param).
  • Updates incidents skill metadata, cheatsheet text, and adds feature/spec/plan documentation.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated no comments.

Show a summary per file
File Description
docs/superpowers/specs/2026-06-22-incidents-set-status-design.md New design spec for incidents set-status behavior and architecture.
docs/superpowers/plans/2026-06-22-incidents-set-status.md New implementation plan outlining tasks, code shape, and tests.
docs/features/incidents-set-status.md New user-facing feature documentation for incidents set-status.
cmd/incidents/changestatus.go New shared helper: status normalization + request building + mutation execution via safety.Wrap.
cmd/incidents/changestatus_test.go Unit tests for status normalization behavior.
cmd/incidents/setstatus.go New set-status command implementation (flags parsing, stdin GUID ingestion, filters parsing).
cmd/incidents/setstatus_test.go Tests covering set-status dry-run preview, filters, search query, stdin, invalid inputs, and --yes posting.
cmd/incidents/resolve.go Refactors resolve to be a thin wrapper around the shared helper.
cmd/incidents/incidents.go Registers the new set-status subcommand under incidents.
cmd/incidents/skill.go Updates incident status notes and adds set-status recipes.
cmd/incidents/types.go Updates cheatsheet text to list all four canonical statuses.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

…ixes

- regenerate skills/armoctl-incidents/SKILL.md for the new set-status command (CI verify gate)
- check json decode/unmarshal errors in set-status tests
- note --stdin as a selection method in the feature doc
- add language tags to fenced code blocks in spec/plan (MD040)
Signed-off-by: Ben <ben@armosec.io>
@matthyx
matthyx merged commit 849088f into main Jun 23, 2026
4 checks passed
@matthyx
matthyx deleted the feat/incidents-set-status branch June 23, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-assisted Created through Armosec AI tooling (armosec-shared-rules plugin) release Trigger release on merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants