Securecoder suppress
Skill nerdy-krishna/securecoder/skills/security/securecoder-suppress
Mark findings as false positives. Writes structured entries to .securecoder/suppressions.json — the source of truth that /securecoder-scan honors when stamping status="suppressed" on matching findings. Eight modes for add / import / show / show <id> / show stale / show expired / remove / expire.From its SKILL.md
npx -y skills add nerdy-krishna/securecoder --skill securecoder-suppressAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 8 commands, including `python3 "<skill-dir>/scripts/suppress.py" add` and 7 more.
SKILL.md
7.0 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it
/securecoder-suppress
You are running the /securecoder-suppress skill. Your job is to mutate .securecoder/suppressions.json (the team-shared false-positive ledger) based on the user's intent. The skill is the source of truth for suppressions — every other skill reads .securecoder/suppressions.json (directly or via the status: "suppressed" field that /securecoder-scan stamps).
What this skill does NOT do. It does not re-run scans. It does not recompute suppression effects against existing findings. Effects materialize the next time
/securecoder-scanruns (whenapply_suppressions.pymatches the updated suppressions file against fresh findings).
Eight modes
All modes invoke the same helper at <skill-dir>/scripts/suppress.py. Interpret the user's natural-language ask and dispatch to the right subcommand.
1. add — add a new entry from a match expression + reason
python3 "<skill-dir>/scripts/suppress.py" add \
--match "rule=B105 and file_glob=tests/**" \
--reason "Test fixtures intentionally hardcode credentials" \
[--expires 2027-01-01] \
[--scope project]
The --match expression accepts either:
- Simple form:
key=value and key=value ...— keys allowed areid,rule,file,file_glob,framework_ref - JSON form:
{"rule": "B105", "file_glob": "tests/**"}
--reason is required. --expires is optional ISO date (entry auto-disabled past that date). --scope defaults to project (only valid value for v1.1.0).
created_at and created_by are auto-populated. created_by uses git config user.email; falls back to "unknown@local".
The helper dedupes by signature (match + reason) — re-adding an identical entry is a no-op.
Natural-language → subcommand mapping:
- "suppress B105 in tests/" →
add --match "rule=B105 and file_glob=tests/**" --reason "..."(ask user for the reason if not supplied) - "suppress this finding" — see the
<finding-id>shortcut below
2. add shortcut — by finding ID
When the user says "suppress finding 5823722d" or pastes a specific finding ID, dispatch to:
python3 "<skill-dir>/scripts/suppress.py" add \
--match '{"id": "5823722d…"}' \
--reason "..."
The reason is REQUIRED — ask the user if they haven't supplied one. Free text, no minimum length.
3. import — batch import from the HTML report's export button
The HTML report's "Export to agent" button generates a /securecoder-suppress import [...] invocation with a JSON array body. Dispatch to:
python3 "<skill-dir>/scripts/suppress.py" import --entries '<json-array>'
--entries accepts either an inline JSON string or a path to a file. The helper validates each entry, dedupes against existing, and reports added / skipped (dup) / skipped (bad) counts.
4. show — list all current entries
python3 "<skill-dir>/scripts/suppress.py" show
Plain-text table: index, match expression, reason, created_at, created_by, expires_at.
5. show --finding <id> — explain why a finding is suppressed
When the user says "why is finding 5823722d suppressed?" or "who suppressed 5823722d?":
python3 "<skill-dir>/scripts/suppress.py" show --finding 5823722d
The helper:
- Looks up the finding in
.securecoder/runs/latest/findings.jsonl - If
status != "suppressed": reports current status and exits. - Otherwise: reads the
suppression_matchfield (suppressions.json#<index>) and displays the corresponding entry verbatim.
6. show --stale — entries that didn't match anything in the last scan
python3 "<skill-dir>/scripts/suppress.py" show --stale
Reads manifest.suppressed_by_entry from .securecoder/runs/latest/manifest.json. Entries with count 0 (and not expired) are likely stale — the code they referenced may have been removed or refactored.
7. show --expired — entries past their expires_at
python3 "<skill-dir>/scripts/suppress.py" show --expired
Lists entries past their expires_at date. These are still in the file (audit trail preserved) but ignored at match time.
8. remove <index> — delete one entry by index
python3 "<skill-dir>/scripts/suppress.py" remove --index 3
Deletes entry at the given index. Indexes are 0-based and refer to the entry's position in the entries array. Use show first to find the right index.
9. expire — purge expired entries
python3 "<skill-dir>/scripts/suppress.py" expire
By default, lists what would be removed and asks the user to re-invoke with --yes to apply. Once confirmed:
python3 "<skill-dir>/scripts/suppress.py" expire --yes
Removes all entries past their expires_at.
What gets written
.securecoder/suppressions.json — team-shared file, checked in:
{
"schema_version": "1.0",
"entries": [
{
"match": { "rule": "B105", "file_glob": "tests/**" },
"scope": "project",
"reason": "Test fixtures intentionally hardcode credentials",
"created_at": "2026-05-14T15:30:00Z",
"created_by": "[email protected]",
"expires_at": null
}
]
}
Where the suppression actually takes effect
/securecoder-suppress does NOT re-run scans. Its only output is the mutated suppressions.json file. Effects materialize the NEXT time /securecoder-scan runs (or /securecoder-secure, since it invokes scan internally), when apply_suppressions.py stamps status: "suppressed" on matching findings.
If the user wants to see the suppression take effect immediately, they should run /securecoder-scan after invoking /securecoder-suppress.
For the pre-commit hook (/securecoder-review's installed hook), the script reads .securecoder/suppressions.json directly — so suppression changes apply on the very next commit attempt without needing a fresh scan.
Failure handling
- Suppressions file missing on read (show modes): treat as zero entries; the show modes still work, just return empty.
- Suppressions file missing on write (add/import/remove/expire): create the file + parent dirs as needed.
- Suppressions file malformed JSON: print a warning, treat as empty; user must manually fix before further edits stick.
- Index out of range on remove: error message with the valid range; exit non-zero.
- Match expression unparseable: error message; exit non-zero.
Invariants
- The file always validates against schema v1.0 after every mutation.
- The
entriesarray is always present (possibly empty). created_atandcreated_byare always populated on new entries by the helper, never the user's job.- Dedupe by signature (
match + reason) prevents accidental duplicate adds. - The file is the SOLE source of truth for suppressions; other skills read it but never mutate it.
What ships with it: 1 file
14.3 KB alongside SKILL.md, 1 of them executable
scripts/
- suppress.pyruns14.3 KB