Skip to content

Narrow ShieldClaw to SQLi-only MVP - #69

Closed
blondres04 wants to merge 7 commits into
mainfrom
codex/sqli-only-mvp
Closed

Narrow ShieldClaw to SQLi-only MVP#69
blondres04 wants to merge 7 commits into
mainfrom
codex/sqli-only-mvp

Conversation

@blondres04

Copy link
Copy Markdown
Owner

What changed

  • Narrows the default MVP support boundary to Semgrep CWE-89 SQL injection.
  • Keeps non-CWE-89 findings visible while preventing default scoring, approval, PoC generation, or detonation.
  • Adds first-class AWAITING_APPROVAL, REJECTED, and DEFERRED lifecycle behavior while preserving legacy SCORED approval compatibility.
  • Clarifies JSON, Markdown, and secondary SARIF output with mvp_support, outcome, and outcome_kind fields.
  • Adds a SQLi MVP unit gate in CI and a manual Docker QA checklist for the approved true-positive and rejected no-detonation cases.
  • Aligns README, package description, changelog, responsible-use/security wording, and existing docs with the SQLi-only claim.

Closes #65
Closes #66
Closes #67
Closes #68

Tests run

  • python -m pytest -m "not integration" -q -> 209 passed, 10 deselected
  • python -m mypy --strict src/
  • python -m ruff format --check .
  • python -m ruff check .

Manual QA

Manual Docker validation is documented in shield-claw/docs/sqli-mvp-validation-checklist.md and should be run before demo/release acceptance:

  • approved CWE-89 finding reaches TRUE_POSITIVE,
  • TRUE_POSITIVE includes exit-code evidence plus Tier-2 corroboration,
  • rejected CWE-89 finding reaches REJECTED,
  • rejected finding has no PoC generation or detonation,
  • non-CWE-89 findings are visible but not scored or detonated by default.

Known deferrals

  • CWE-78 and CWE-434 validation paths
  • SARIF release gating
  • patching / patch verification
  • web UI
  • broader vulnerability-class support

Notes

Docker integration/manual QA was not run on this machine because Docker Desktop was not running. Pre-existing untracked generated docs under shield-claw/docs/... were intentionally left uncommitted.

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

This PR narrows ShieldClaw’s default MVP validation lane to Semgrep CWE-89 (SQL injection) only, adds explicit “pending approval / rejected / deferred” lifecycle behavior, and updates report outputs + CI/docs to reflect the SQLi-only support claim.

Changes:

  • Restricts default dynamic validation/scoring/approval/detonation to CWE-89, while keeping non-CWE-89 findings visible as deferred/static-only by default.
  • Introduces/normalizes lifecycle states (AWAITING_APPROVAL, REJECTED, DEFERRED) and preserves legacy SCORED approval compatibility.
  • Enhances JSON/Markdown/SARIF reporting with MVP support and outcome metadata; adds a focused SQLi MVP unit gate + manual Docker checklist documentation.

Reviewed changes

Copilot reviewed 22 out of 23 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
shield-claw/tests/test_triage_classifier.py Updates classifier expectations for SQLi-only default and adds override/guard coverage.
shield-claw/tests/test_report_builder.py Updates report assertions to validate new MVP/outcome metadata and rejected behavior.
shield-claw/tests/test_pipeline_e2e.py Adjusts integration expectations for terminal states under the new lifecycle.
shield-claw/tests/test_orchestrator_resume.py Updates resume/scoring expectations to use AWAITING_APPROVAL and adds SQLi-only scoring gate test.
shield-claw/tests/test_approval.py Updates fixtures/assumptions and adds CLI compatibility test for legacy SCORED rows.
shield-claw/tests/fixtures/semgrep_5sqli.json Adds a 5-finding SQLi-only Semgrep fixture for deterministic tests.
shield-claw/src/shieldclaw/triage/cwe_verdicts.toml Changes default CWE mapping so only CWE-89 is dynamically verifiable by default.
shield-claw/src/shieldclaw/triage/classifier.py Normalizes CWE parsing and adds SQLi-only “deferred boundary” reasoning.
shield-claw/src/shieldclaw/reporting/builder.py Adds mvp_support + outcome metadata across JSON/Markdown/SARIF serialization.
shield-claw/src/shieldclaw/orchestrator.py Moves supported findings to AWAITING_APPROVAL, defers others, and keeps legacy SCORED approval compatibility.
shield-claw/src/shieldclaw/models.py Adds MVP CWE helpers + expands FindingState enum for new lifecycle states.
shield-claw/src/shieldclaw/main.py Filters approval candidates to dynamically-verifiable findings across AWAITING_APPROVAL/SCORED.
shield-claw/pyproject.toml Updates package description to reflect the SQLi-focused MVP claim.
shield-claw/docs/sqli-mvp-validation-checklist.md Adds a manual Docker checklist for approved TP + rejected no-detonation MVP validation.
shield-claw/docs/prd-sast-pipeline-v02.md Updates product design doc to reflect SQLi-only MVP scope and lifecycle changes.
shield-claw/docs/adrs/007-hitl-approval-model.md Updates approval ADR language/workflow for SQLi-only MVP + legacy compatibility.
shield-claw/CLAUDE.md Updates contributor guidance and invariants to SQLi-only MVP language.
SECURITY.md Updates security policy wording/scope to match SQLi-only MVP claim and expectations.
RESPONSIBLE_USE.md Updates responsible-use policy to reflect SQLi-only MVP boundary and experiment constraints.
README.md Updates README claims, architecture diagram labels, outputs, and limitations to SQLi-only MVP.
CHANGELOG.md Documents MVP narrowing + new states + reporting metadata and QA gate additions.
.gitignore Ignores .codex/ and normalizes an entry formatting change.
.github/workflows/ci.yml Adds a focused SQLi MVP unit gate step to CI.

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


def _mvp_support_metadata(finding: SASTFindingReport) -> dict[str, str]:
"""Describe whether a finding is inside the default SQLi-only MVP boundary."""
if has_mvp_supported_cwe(finding.cwe):
Comment on lines +199 to +203
if deferred:
return TriagedFinding(
finding=finding,
verdict=TriageVerdict.STATIC_ONLY,
reason=(
Comment on lines +225 to +229
def _get_approval_ready_findings(store: object, scan_id: str) -> list[Any]:
"""Return new and legacy approval-pending dynamically verifiable rows."""
from shieldclaw.persistence.store import FindingRow, ScanStore

assert isinstance(store, ScanStore)
@blondres04 blondres04 closed this Jul 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants