{
  "artifact_id": "sample-1",
  "count": 8,
  "severity_spread": {
    "critical": 1,
    "high": 3,
    "medium": 3,
    "low": 1,
    "info": 0
  },
  "findings": [
    {
      "id": "sample-1/f-001",
      "rule": "SEC-EVAL-001",
      "family": "security",
      "severity": "critical",
      "title": "Direct call to `eval()` on user-controlled input",
      "file": "src/handlers/dangerous.ts",
      "line": 4,
      "symbol": "dangerousHandler",
      "evidence": {
        "source_extract": "return eval(input);",
        "confidence": 0.99,
        "reasoning": "The parameter `input: string` reaches a call to the global `eval` builtin with no sanitisation. Any caller controls arbitrary code execution.",
        "detector": "svp-parser + svp-verification (data-flow to sink)"
      },
      "reachable_from": [
        "src/index.ts:main → dangerousHandler(\"2+2\")"
      ],
      "recommendation": "Replace `eval` with a scoped expression evaluator, or reject the endpoint entirely."
    },
    {
      "id": "sample-1/f-002",
      "rule": "SEC-SECRET-NAME-001",
      "family": "security",
      "severity": "low",
      "title": "Symbol name matches secret-material heuristic",
      "file": "src/auth/secrets.ts",
      "line": 5,
      "symbol": "getSecretKey",
      "evidence": {
        "source_extract": "export function getSecretKey(): string { ... }",
        "confidence": 0.42,
        "reasoning": "Function name matches the pattern `get*Secret*` — a name-based signal that this may return sensitive material. Body currently returns an env value with a plaintext fallback; validate that no real secret is inlined in future.",
        "detector": "svp-verification (name heuristic)"
      },
      "reachable_from": [
        "src/index.ts:main → getSecretKey()"
      ],
      "recommendation": "Confirm the fallback is never taken in production; assert `SVP_DEMO_SECRET` presence at startup."
    },
    {
      "id": "sample-1/f-003",
      "rule": "QUAL-LONG-001",
      "family": "quality",
      "severity": "medium",
      "title": "Function body exceeds physical length threshold (≥200 lines)",
      "file": "src/handlers/long.ts",
      "line": 3,
      "symbol": "longHandler",
      "evidence": {
        "source_extract": "export function longHandler(): number { ... 220+ lines ... }",
        "confidence": 1,
        "reasoning": "Physical LoC ≥ 200 within a single function body.",
        "detector": "svp-parser (structural metric)"
      },
      "recommendation": "Extract logical sub-steps into helper functions."
    },
    {
      "id": "sample-1/f-004",
      "rule": "QUAL-PARAMS-001",
      "family": "quality",
      "severity": "medium",
      "title": "Function accepts more than 7 parameters",
      "file": "src/handlers/manyparams.ts",
      "line": 3,
      "symbol": "manyParamsHandler",
      "evidence": {
        "source_extract": "export function manyParamsHandler(a, b, c, d, e, f, g, h, i)",
        "confidence": 1,
        "reasoning": "9 formal parameters — over the configured threshold of 7.",
        "detector": "svp-parser (structural metric)"
      },
      "recommendation": "Group related parameters into an options object."
    },
    {
      "id": "sample-1/f-005",
      "rule": "ARCH-FANOUT-001",
      "family": "architecture",
      "severity": "high",
      "title": "Excessive fan-out (\"god function\") — 42 outgoing call edges",
      "file": "src/handlers/god.ts",
      "line": 45,
      "symbol": "godHandler",
      "evidence": {
        "source_extract": "godHandler calls a() b() c() ... ap() — 42 distinct targets",
        "confidence": 1,
        "reasoning": "Symbol fan-out is 42; architectural policy caps intra-module fan-out at 20. This handler concentrates orchestration that should live in a coordinator.",
        "detector": "svp-knowledge-graph (call-edge count)"
      },
      "reachable_from": [
        "src/index.ts:main → godHandler()"
      ],
      "recommendation": "Split into per-responsibility coordinators; consider a command bus pattern."
    },
    {
      "id": "sample-1/f-006",
      "rule": "SC-CVE-LODASH-001",
      "family": "supply-chain",
      "severity": "high",
      "title": "Direct dependency `lodash@4.17.20` has known CVEs (OSV)",
      "file": "package.json",
      "line": 8,
      "evidence": {
        "source_extract": "\"lodash\": \"4.17.20\"",
        "confidence": 1,
        "reasoning": "Version 4.17.20 predates fixes for CVE-2020-8203 (prototype pollution) and CVE-2021-23337 (command injection via `template`). Fixed in 4.17.21+.",
        "detector": "svp-dependency + OSV feed"
      },
      "recommendation": "Bump to `lodash ^4.17.21` (patch-only upgrade, no API break)."
    },
    {
      "id": "sample-1/f-007",
      "rule": "SC-CVE-EXPRESS-001",
      "family": "supply-chain",
      "severity": "medium",
      "title": "Direct dependency `express@4.17.1` is behind current stable",
      "file": "package.json",
      "line": 9,
      "evidence": {
        "source_extract": "\"express\": \"4.17.1\"",
        "confidence": 0.9,
        "reasoning": "Version 4.17.1 predates several 4.x security patches; current 4.x stable resolves multiple ReDoS and prototype-pollution issues.",
        "detector": "svp-dependency + OSV feed"
      },
      "recommendation": "Bump to latest 4.x (`^4.19.2` at time of writing)."
    },
    {
      "id": "sample-1/f-008",
      "rule": "SC-CVE-JWT-001",
      "family": "supply-chain",
      "severity": "high",
      "title": "Direct dependency `jsonwebtoken@8.5.1` has known CVEs",
      "file": "package.json",
      "line": 10,
      "evidence": {
        "source_extract": "\"jsonwebtoken\": \"8.5.1\"",
        "confidence": 0.98,
        "reasoning": "Version 8.5.1 is affected by CVE-2022-23539 (weak signature verification when `algorithms` is not passed) and CVE-2022-23540/23541 (algorithm confusion). Fixed in 9.0.0.",
        "detector": "svp-dependency + OSV feed"
      },
      "recommendation": "Bump to `jsonwebtoken ^9.0.2` and pass an explicit `algorithms` allowlist to `jwt.verify`."
    }
  ]
}
