rafter-cli 0.8.6__tar.gz → 0.8.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/PKG-INFO +1 -1
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/pyproject.toml +1 -1
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/mcp_server.py +35 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/policy_loader.py +3 -3
- rafter_cli-0.8.7/rafter_cli/core/suppression_writer.py +111 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/rafter-security-skill.md +1 -1
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/finding-triage.md +3 -2
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/README.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/__main__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/agent.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/agent_components.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/backend.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/brief.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/ci.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/docs.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/hook.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/issues/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/issues/dedup.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/issues/github_client.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/issues/issue_builder.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/issues/issues_app.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/notify.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/policy.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/report.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/scan.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/skill.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/commands/skill_remote.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/audit_logger.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/command_interceptor.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/config_manager.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/config_schema.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/custom_patterns.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/docs_loader.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/hook_control.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/pattern_engine.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/core/risk_rules.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/agents/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/agents/rafter.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter-code-review.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter-secure-design.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter-skill-review.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter-code-review.mdc +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter-secure-design.mdc +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter-skill-review.mdc +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter.mdc +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/pre-commit-hook.sh +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/pre-push-hook.sh +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/SKILL.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/backend.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/cli-reference.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/guardrails.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/shift-left.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/SKILL.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/api.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/asvs.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/cwe-top25.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/investigation-playbook.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/llm.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/web-app.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/SKILL.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/api-design.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/auth.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/data-storage.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/dependencies.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/deployment.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/ingestion.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/standards-pointers.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/threat-modeling.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/SKILL.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/docs/authorship-provenance.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/docs/changelog-review.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/docs/data-practices.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/docs/malware-indicators.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/docs/prompt-injection.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/docs/telemetry.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter-code-review.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter-secure-design.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter-skill-review.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter.md +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/scanners/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/scanners/betterleaks.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/scanners/regex_scanner.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/scanners/secret_patterns.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/scanners/union.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/utils/__init__.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/utils/api.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/utils/binary_manager.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/utils/formatter.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/utils/git.py +0 -0
- {rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/utils/skill_manager.py +0 -0
|
@@ -175,6 +175,18 @@ def handle_get_docs_resource() -> str:
|
|
|
175
175
|
return json.dumps(handle_list_docs(), indent=2)
|
|
176
176
|
|
|
177
177
|
|
|
178
|
+
def handle_suppress_finding(
|
|
179
|
+
path: str,
|
|
180
|
+
rules: list[str] | None = None,
|
|
181
|
+
reason: str | None = None,
|
|
182
|
+
) -> dict:
|
|
183
|
+
"""Persist a false-positive suppression into the project's .rafter.yml."""
|
|
184
|
+
from ..core.suppression_writer import write_suppression
|
|
185
|
+
|
|
186
|
+
result = write_suppression([path], rules=rules, reason=reason)
|
|
187
|
+
return {"ok": True, **result}
|
|
188
|
+
|
|
189
|
+
|
|
178
190
|
# ── MCP server factory ────────────────────────────────────────────────
|
|
179
191
|
|
|
180
192
|
|
|
@@ -249,6 +261,29 @@ def create_mcp_server():
|
|
|
249
261
|
"""
|
|
250
262
|
return json.dumps(handle_get_doc(id_or_tag, refresh))
|
|
251
263
|
|
|
264
|
+
@mcp.tool()
|
|
265
|
+
def suppress_finding(
|
|
266
|
+
path: str,
|
|
267
|
+
rules: list[str] | None = None,
|
|
268
|
+
reason: str | None = None,
|
|
269
|
+
) -> str:
|
|
270
|
+
"""Triage a false positive by persisting a suppression rule into .rafter.yml.
|
|
271
|
+
|
|
272
|
+
Use when a scan_secrets finding (or a remote scan finding) is a confirmed
|
|
273
|
+
false positive — e.g. a test fixture or sample credential. Suppressed
|
|
274
|
+
findings still surface under '_suppressed' in scan output, so the decision
|
|
275
|
+
is reviewable and version-controlled. Always include a reason.
|
|
276
|
+
|
|
277
|
+
Args:
|
|
278
|
+
path: File path or glob to suppress findings in (e.g. 'test/fixtures/**').
|
|
279
|
+
rules: Specific rules to suppress, matched case-insensitively against a
|
|
280
|
+
finding's rule name OR rule id — e.g. 'AWS Access Key' (local pattern
|
|
281
|
+
name) or 'R-6D5E2' (remote SAST/SCA rule id). Omit to suppress all
|
|
282
|
+
rules for the path. Honored by both local scans and remote `rafter run`.
|
|
283
|
+
reason: Why this is a false positive — persisted with the rule. Strongly recommended.
|
|
284
|
+
"""
|
|
285
|
+
return json.dumps(handle_suppress_finding(path, rules, reason))
|
|
286
|
+
|
|
252
287
|
@mcp.resource("rafter://config")
|
|
253
288
|
def config_resource() -> str:
|
|
254
289
|
"""Current Rafter configuration."""
|
|
@@ -30,13 +30,13 @@ POLICY_FILENAMES = [".rafter.yml", ".rafter.yaml"]
|
|
|
30
30
|
_KNOWN_DOC_KEYS = {"id", "path", "url", "description", "tags", "cache"}
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
def find_policy_file() -> Path | None:
|
|
34
|
-
"""Walk from cwd up to git root looking for a policy file.
|
|
33
|
+
def find_policy_file(start_dir: str | Path | None = None) -> Path | None:
|
|
34
|
+
"""Walk from ``start_dir`` (default cwd) up to git root looking for a policy file.
|
|
35
35
|
|
|
36
36
|
Returns the first candidate that exists, in the precedence order
|
|
37
37
|
declared by ``POLICY_FILE_CANDIDATES``.
|
|
38
38
|
"""
|
|
39
|
-
cwd = Path.cwd()
|
|
39
|
+
cwd = Path(start_dir) if start_dir else Path.cwd()
|
|
40
40
|
root = get_git_root()
|
|
41
41
|
stop = Path(root) if root else cwd.anchor and Path(cwd.anchor)
|
|
42
42
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""Persist finding suppressions into the project's .rafter.yml ignore list.
|
|
2
|
+
|
|
3
|
+
Mirrors node/src/core/suppression-writer.ts — keep both in sync.
|
|
4
|
+
"""
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
from ..utils.git import get_git_root
|
|
11
|
+
from .policy_loader import find_policy_file
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _rule_key(paths: list[str], rules: list[str] | None) -> str:
|
|
15
|
+
"""Order- and duplicate-insensitive identity for an ignore rule.
|
|
16
|
+
|
|
17
|
+
Two rules are "the same" if they target the same set of paths and the
|
|
18
|
+
same set of rule names. Reason is excluded — re-suppressing the same
|
|
19
|
+
scope just updates the reason.
|
|
20
|
+
"""
|
|
21
|
+
def norm(xs: list[str] | None) -> list[str]:
|
|
22
|
+
return sorted({str(x) for x in (xs or [])})
|
|
23
|
+
|
|
24
|
+
return json.dumps({"paths": norm(paths), "rules": norm(rules)}, sort_keys=True)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def write_suppression(
|
|
28
|
+
paths: list[str],
|
|
29
|
+
rules: list[str] | None = None,
|
|
30
|
+
reason: str | None = None,
|
|
31
|
+
cwd: str | Path | None = None,
|
|
32
|
+
) -> dict:
|
|
33
|
+
"""Persist a finding suppression into the project's .rafter.yml ignore list.
|
|
34
|
+
|
|
35
|
+
Resolves the policy file via the same precedence the loader uses; if none
|
|
36
|
+
exists, creates a canonical ``.rafter.yml`` at the git root (or ``cwd``).
|
|
37
|
+
|
|
38
|
+
Merge semantics: if an existing ignore rule targets the same paths + rules,
|
|
39
|
+
its reason is updated in place rather than appending a duplicate.
|
|
40
|
+
|
|
41
|
+
``cwd`` overrides the base directory for resolution (defaults to the process cwd).
|
|
42
|
+
|
|
43
|
+
Returns a dict: {file, action, entry, suppression_count}.
|
|
44
|
+
"""
|
|
45
|
+
import yaml
|
|
46
|
+
|
|
47
|
+
norm_paths = [str(p) for p in (paths or []) if str(p)]
|
|
48
|
+
if not norm_paths:
|
|
49
|
+
raise ValueError('"paths" must be a non-empty list of file paths or globs.')
|
|
50
|
+
norm_rules = [str(r) for r in rules if str(r)] if isinstance(rules, list) else None
|
|
51
|
+
norm_reason = reason.strip() if isinstance(reason, str) and reason.strip() else None
|
|
52
|
+
base_dir = str(cwd) if cwd else str(Path.cwd())
|
|
53
|
+
|
|
54
|
+
target = find_policy_file(base_dir)
|
|
55
|
+
raw: dict = {}
|
|
56
|
+
|
|
57
|
+
if target and Path(target).exists():
|
|
58
|
+
parsed = yaml.safe_load(Path(target).read_text())
|
|
59
|
+
raw = parsed if isinstance(parsed, dict) else {}
|
|
60
|
+
action = "appended"
|
|
61
|
+
else:
|
|
62
|
+
root = get_git_root() or base_dir
|
|
63
|
+
target = Path(root) / ".rafter.yml"
|
|
64
|
+
action = "created"
|
|
65
|
+
|
|
66
|
+
target = Path(target)
|
|
67
|
+
ignore_list = raw.get("ignore") if isinstance(raw.get("ignore"), list) else []
|
|
68
|
+
|
|
69
|
+
new_entry: dict = {"paths": norm_paths}
|
|
70
|
+
if norm_rules:
|
|
71
|
+
new_entry["rules"] = norm_rules
|
|
72
|
+
if norm_reason:
|
|
73
|
+
new_entry["reason"] = norm_reason
|
|
74
|
+
|
|
75
|
+
key = _rule_key(norm_paths, norm_rules)
|
|
76
|
+
existing = next(
|
|
77
|
+
(
|
|
78
|
+
e
|
|
79
|
+
for e in ignore_list
|
|
80
|
+
if isinstance(e, dict)
|
|
81
|
+
and isinstance(e.get("paths"), list)
|
|
82
|
+
and _rule_key(e["paths"], e.get("rules")) == key
|
|
83
|
+
),
|
|
84
|
+
None,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if existing is not None:
|
|
88
|
+
if norm_reason:
|
|
89
|
+
existing["reason"] = norm_reason
|
|
90
|
+
else:
|
|
91
|
+
existing.pop("reason", None)
|
|
92
|
+
if action != "created":
|
|
93
|
+
action = "updated"
|
|
94
|
+
entry = dict(new_entry)
|
|
95
|
+
if existing.get("reason"):
|
|
96
|
+
entry["reason"] = existing["reason"]
|
|
97
|
+
else:
|
|
98
|
+
ignore_list.append(new_entry)
|
|
99
|
+
entry = new_entry
|
|
100
|
+
|
|
101
|
+
raw["ignore"] = ignore_list
|
|
102
|
+
|
|
103
|
+
target.parent.mkdir(parents=True, exist_ok=True)
|
|
104
|
+
target.write_text(yaml.safe_dump(raw, sort_keys=False, default_flow_style=False))
|
|
105
|
+
|
|
106
|
+
return {
|
|
107
|
+
"file": str(target),
|
|
108
|
+
"action": action,
|
|
109
|
+
"entry": entry,
|
|
110
|
+
"suppression_count": len(ignore_list),
|
|
111
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: rafter-security
|
|
3
3
|
description: Security toolkit for AI workflows. Use when scanning code or repos for vulnerabilities, auditing third-party skills/MCPs/agent configs before installing, evaluating shell commands before running them, or generating secure design questions for new features. Provides `rafter run` (remote SAST + SCA, needs RAFTER_API_KEY), `rafter secrets` (offline secrets-only), `rafter agent exec --dry-run` (command-risk classification), and `rafter skill review`.
|
|
4
|
-
version: 0.8.
|
|
4
|
+
version: 0.8.7
|
|
5
5
|
homepage: https://rafter.so
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/finding-triage.md
RENAMED
|
@@ -53,7 +53,7 @@ If the finding is a leaked secret that was committed:
|
|
|
53
53
|
|
|
54
54
|
## Suppression — When It's OK
|
|
55
55
|
|
|
56
|
-
Suppress only when the finding is a real false positive *for this context*, with a written reason.
|
|
56
|
+
Suppress only when the finding is a real false positive *for this context*, with a written reason. Three mechanisms:
|
|
57
57
|
|
|
58
58
|
- **`.rafter.yml`**: add an `ignore:` rule naming the path(s), the rule(s), and a `reason` (your evidence). Repo-tied; persists across scans:
|
|
59
59
|
```yaml
|
|
@@ -62,7 +62,8 @@ Suppress only when the finding is a real false positive *for this context*, with
|
|
|
62
62
|
rules: ["AWS Access Key ID"] # omit `rules` to suppress every finding on those paths
|
|
63
63
|
reason: "fake test keys — no live path"
|
|
64
64
|
```
|
|
65
|
-
|
|
65
|
+
Each `rules` entry matches (case-insensitively) the finding's **rule name** (e.g. `AWS Access Key ID`) **or** its **rule id** (e.g. `R-6D5E2`) — use the name for local pattern findings, the id for remote SAST/SCA findings. Path globs are gitignore-style: `*` stays within a path segment, `**` crosses segments, a bare name matches the basename. The same `.rafter.yml ignore` block is honored by **local** scans and **remote `rafter run`** alike. Suppressed findings move into a `_suppressed[]` array and don't affect the exit code — you only fail on a *non-suppressed* finding. Docs: https://docs.rafter.so/suppression
|
|
66
|
+
- **MCP `suppress_finding` tool**: agents can triage a false positive directly through the MCP — it writes the same `.rafter.yml` `ignore` rule above (path, optional rule names, reason). No hand-editing required.
|
|
66
67
|
- **Baseline**: `rafter agent baseline create` snapshots current findings; scan with `rafter scan --baseline` so only *new* findings surface. Good for adopting Rafter on a legacy codebase without a big bang.
|
|
67
68
|
|
|
68
69
|
Never suppress by:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter-code-review.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter-secure-design.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/continue-rules/rafter-skill-review.md
RENAMED
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter-code-review.mdc
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter-secure-design.mdc
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/cursor-rules/rafter-skill-review.mdc
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter/docs/cli-reference.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/SKILL.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/api.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/asvs.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/llm.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-code-review/docs/web-app.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-secure-design/docs/auth.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/skills/rafter-skill-review/SKILL.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter-code-review.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter-secure-design.md
RENAMED
|
File without changes
|
{rafter_cli-0.8.6 → rafter_cli-0.8.7}/rafter_cli/resources/windsurf-rules/rafter-skill-review.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|