{
  "schema_version": 1,
  "generator": "pandaward 0.2.1",
  "generated_at": "2026-10-28T20:49:03Z",
  "project": "acme-shop",
  "assessment": {
    "id": "asmt_0001_20261028T204903Z",
    "seq": 1,
    "git_commit": "5e17870a6457947826be30aa316c027412ea5492",
    "git_dirty": false,
    "profile": "local-passive",
    "config_hash": "95839c1b2db37ed1cb4282275417cb7f3ddd51fa11bf60dcf5f748f7c5765260",
    "catalog_version": "2026.10-m4",
    "started_at": "2026-10-28T20:49:03Z",
    "ended_at": "2026-10-28T20:49:03Z",
    "status": "COMPLETE"
  },
  "attestation": "Automated technical security assessment. Not a certification, attestation, legal opinion or independently signed penetration test, and not a guarantee that no vulnerabilities exist. Only the controls listed as PASS were decisively checked, and only for the stated scope, method and point in time.",
  "coverage": {
    "applicable_controls": 52,
    "decisive_controls": 21,
    "decisive_control_coverage": 0.40384615384615385,
    "edges_total": 15,
    "edges_verified": 0,
    "edges_failed": 5,
    "edges_blocked_or_inconclusive": 10,
    "stale_files": 0,
    "note": "Coverage counts decisively tested controls (PASS/FAIL) over applicable controls. It is not a percentage of vulnerabilities found. BLOCKED, UNSUPPORTED, SUSPECTED, INCONCLUSIVE, ERROR and STALE never count as secure."
  },
  "controls": [
    {
      "id": "A-001",
      "domain": "A",
      "title": "Repository inventory walk completed without unreadable or skipped files",
      "method": "static",
      "status": "PASS",
      "reason": "9 text files analyzed, none skipped",
      "adapter": "builtin-inventory"
    },
    {
      "id": "A-002",
      "domain": "A",
      "title": "Externally reachable routes enumerated with file references",
      "method": "static",
      "status": "INCONCLUSIVE",
      "reason": "4 HTTP routes, 0 GraphQL operations, 0 gRPC methods, 0 queue consumers and 0 cron jobs extracted heuristically with file and line (`pandaward routes`); completeness is not proven without a contract or runtime crawl",
      "adapter": "builtin-inventory"
    },
    {
      "id": "A-003",
      "domain": "A",
      "title": "Declared API contract (OpenAPI) matches discovered routes",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "3 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-inventory",
      "evidence_ids": [
        "ev_efa0768a93861314",
        "ev_47d3f7f67228fdd6",
        "ev_2de440fb1038ae7e"
      ]
    },
    {
      "id": "A-004",
      "domain": "A",
      "title": "Asset owners, trust boundaries and abuse cases reviewed",
      "method": "manual",
      "status": "BLOCKED",
      "reason": "manual-assisted review required (/pandaward:review); not decided by automation"
    },
    {
      "id": "B-001",
      "domain": "B",
      "title": "JWT verification is not disabled and does not accept the 'none' algorithm",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_ba4887d7098ce9c5"
      ],
      "refs": [
        "CWE-347"
      ]
    },
    {
      "id": "B-002",
      "domain": "B",
      "title": "Session cookies are not explicitly configured without Secure/HttpOnly",
      "method": "static",
      "status": "PASS",
      "reason": "check completed with no signal (code heuristics); PASS applies to this check only",
      "adapter": "builtin-code",
      "refs": [
        "CWE-614",
        "CWE-1004"
      ]
    },
    {
      "id": "B-003",
      "domain": "B",
      "title": "Login, reset and MFA state machine tested with negative cases",
      "method": "runtime",
      "status": "UNSUPPORTED",
      "reason": "runtime adapter for profile staging-active is not implemented in this release; use manual-assisted review",
      "refs": [
        "API2:2023"
      ]
    },
    {
      "id": "B-004",
      "domain": "B",
      "title": "Session expiry and revocation enforced server-side",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs an identity with revoked: true and authorization_checks in an approved scope manifest, then `pandaward test --profile staging-active`",
      "adapter": "authz",
      "refs": [
        "CWE-613"
      ]
    },
    {
      "id": "C-001",
      "domain": "C",
      "title": "Object-level authorization enforced on parameterized routes (BOLA)",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs identities and authorization_checks in an approved scope manifest, then `pandaward test --profile staging-active`",
      "adapter": "authz",
      "refs": [
        "API1:2023",
        "CWE-639"
      ]
    },
    {
      "id": "C-002",
      "domain": "C",
      "title": "Function-level authorization enforced on privileged routes",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs identities and authorization_checks in an approved scope manifest, then `pandaward test --profile staging-active`",
      "adapter": "authz",
      "refs": [
        "API5:2023",
        "CWE-285"
      ]
    },
    {
      "id": "C-003",
      "domain": "C",
      "title": "Authorization checks reviewed for every route handler",
      "method": "manual",
      "status": "BLOCKED",
      "reason": "manual-assisted review required (/pandaward:review); not decided by automation",
      "refs": [
        "CWE-862"
      ]
    },
    {
      "id": "D-001",
      "domain": "D",
      "title": "No dynamic code evaluation (eval/new Function/exec of strings)",
      "method": "static",
      "status": "FAIL",
      "reason": "2 confirmed observation(s)",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_a9c4d034c668acc8",
        "ev_7eb1da32ab0560fe"
      ],
      "refs": [
        "CWE-95"
      ]
    },
    {
      "id": "D-002",
      "domain": "D",
      "title": "No shell command construction through a shell interpreter",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s), 1 suspected",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_94913aefcc6346ee",
        "ev_18bcf670b9fe88b6"
      ],
      "refs": [
        "CWE-78"
      ]
    },
    {
      "id": "D-003",
      "domain": "D",
      "title": "No SQL statements built by string concatenation or interpolation",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_9163cd2dde765988"
      ],
      "refs": [
        "CWE-89"
      ]
    },
    {
      "id": "D-004",
      "domain": "D",
      "title": "No unsafe deserialization APIs on untrusted data",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_45edd1ca1b90d972"
      ],
      "refs": [
        "CWE-502"
      ]
    },
    {
      "id": "D-005",
      "domain": "D",
      "title": "Injection probes executed against approved target",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs zap.active_scan: true in an approved scope manifest, ZAP installed and `pandaward test --profile staging-active`",
      "adapter": "zap"
    },
    {
      "id": "D-006",
      "domain": "D",
      "title": "Semgrep data-flow rules (SSRF, path traversal, template injection) and project rules report no findings",
      "method": "external",
      "status": "BLOCKED",
      "reason": "semgrep is not installed (optional; run `pandaward doctor`)",
      "adapter": "semgrep"
    },
    {
      "id": "E-001",
      "domain": "E",
      "title": "No high-confidence secret patterns in repository files",
      "method": "static",
      "status": "FAIL",
      "reason": "2 confirmed observation(s)",
      "adapter": "builtin-secrets",
      "evidence_ids": [
        "ev_4fc7c8c69e031156",
        "ev_17b39394ce37dd0a"
      ],
      "refs": [
        "CWE-798"
      ]
    },
    {
      "id": "E-002",
      "domain": "E",
      "title": "Environment and credential files are not tracked in git",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-secrets",
      "evidence_ids": [
        "ev_2b3c5175a0b4065c"
      ],
      "refs": [
        "CWE-538"
      ]
    },
    {
      "id": "E-003",
      "domain": "E",
      "title": "TLS certificate verification is not disabled in code",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_e8d11c07675dc9ab"
      ],
      "refs": [
        "CWE-295"
      ]
    },
    {
      "id": "E-004",
      "domain": "E",
      "title": "No weak hash or non-cryptographic random used for security values",
      "method": "static",
      "status": "PASS",
      "reason": "check completed with no signal (code heuristics); PASS applies to this check only",
      "adapter": "builtin-code",
      "refs": [
        "CWE-327",
        "CWE-338"
      ]
    },
    {
      "id": "E-005",
      "domain": "E",
      "title": "Gitleaks reports no secrets",
      "method": "external",
      "status": "BLOCKED",
      "reason": "gitleaks is not installed (optional; run `pandaward doctor`)",
      "adapter": "gitleaks",
      "refs": [
        "CWE-798"
      ]
    },
    {
      "id": "F-001",
      "domain": "F",
      "title": "Business invariants for money and entitlement flows documented and reviewed",
      "method": "manual",
      "status": "BLOCKED",
      "reason": "manual-assisted review required (/pandaward:review); not decided by automation"
    },
    {
      "id": "F-002",
      "domain": "F",
      "title": "Idempotency and double-processing tested with synthetic fixtures",
      "method": "runtime",
      "status": "UNSUPPORTED",
      "reason": "runtime adapter for profile staging-active is not implemented in this release; use manual-assisted review",
      "refs": [
        "CWE-362"
      ]
    },
    {
      "id": "G-001",
      "domain": "G",
      "title": "Webhook handlers verify a signature before acting on the payload",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_fdf34989adaac10f"
      ],
      "refs": [
        "CWE-345"
      ]
    },
    {
      "id": "G-002",
      "domain": "G",
      "title": "Runtime API authorization matches the declared contract",
      "method": "runtime",
      "status": "UNSUPPORTED",
      "reason": "runtime adapter for profile staging-active is not implemented in this release; use manual-assisted review",
      "refs": [
        "API1:2023",
        "API3:2023"
      ]
    },
    {
      "id": "H-001",
      "domain": "H",
      "title": "No raw HTML injection sinks (innerHTML, dangerouslySetInnerHTML, v-html, |safe)",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_3492a3599d7b8d70"
      ],
      "refs": [
        "CWE-79"
      ]
    },
    {
      "id": "H-002",
      "domain": "H",
      "title": "CORS is not configured as wildcard together with credentials",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_8f75c59732ca936d"
      ],
      "refs": [
        "CWE-942"
      ]
    },
    {
      "id": "H-003",
      "domain": "H",
      "title": "Security response headers present on approved deployed target",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs `pandaward test --profile production-observe` with an approved scope manifest",
      "adapter": "observe-headers",
      "refs": [
        "CWE-693"
      ]
    },
    {
      "id": "I-001",
      "domain": "I",
      "title": "Every package manifest has a committed lockfile",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-supply",
      "evidence_ids": [
        "ev_e081c5b1020366d9"
      ],
      "refs": [
        "CWE-829"
      ]
    },
    {
      "id": "I-002",
      "domain": "I",
      "title": "Dependencies with install-time scripts are listed for review",
      "method": "static",
      "status": "PASS",
      "reason": "check completed with no signal (lockfiles, install scripts, requirement pins, MCP configs); PASS applies to this check only",
      "adapter": "builtin-supply",
      "refs": [
        "CWE-506"
      ]
    },
    {
      "id": "I-003",
      "domain": "I",
      "title": "No known-vulnerable dependencies in an advisory database",
      "method": "external",
      "status": "BLOCKED",
      "reason": "osv-scanner is not installed (optional; run `pandaward doctor`)",
      "adapter": "osv-scanner",
      "refs": [
        "CWE-1395"
      ]
    },
    {
      "id": "I-004",
      "domain": "I",
      "title": "Python requirements pinned to exact versions",
      "method": "static",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'python_reqs' assets found in inventory (review this decision)",
      "adapter": "builtin-supply",
      "refs": [
        "CWE-829"
      ]
    },
    {
      "id": "J-001",
      "domain": "J",
      "title": "Container images do not run as root",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-infra",
      "evidence_ids": [
        "ev_2dd232b952152e08"
      ],
      "refs": [
        "CWE-250"
      ]
    },
    {
      "id": "J-002",
      "domain": "J",
      "title": "Container base images pinned (no latest or missing tag)",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-infra",
      "evidence_ids": [
        "ev_98bb7a66c22d7481"
      ],
      "refs": [
        "CWE-829"
      ]
    },
    {
      "id": "J-003",
      "domain": "J",
      "title": "No privileged containers or host networking in compose/Kubernetes",
      "method": "static",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'orchestration' assets found in inventory (review this decision)",
      "adapter": "builtin-infra",
      "refs": [
        "CWE-250"
      ]
    },
    {
      "id": "J-004",
      "domain": "J",
      "title": "IaC does not expose public storage or world-open admin ports",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s), 1 suspected",
      "adapter": "builtin-infra",
      "evidence_ids": [
        "ev_4f9bf0d255e934f1",
        "ev_822dc4e9c892428a"
      ],
      "refs": [
        "CWE-284"
      ]
    },
    {
      "id": "J-005",
      "domain": "J",
      "title": "Trivy reports no IaC misconfigurations",
      "method": "external",
      "status": "BLOCKED",
      "reason": "trivy is not installed (optional; run `pandaward doctor`)",
      "adapter": "trivy"
    },
    {
      "id": "K-001",
      "domain": "K",
      "title": "Android manifest: not debuggable, no backup, no cleartext traffic",
      "method": "static",
      "status": "FAIL",
      "reason": "2 confirmed observation(s)",
      "adapter": "builtin-mobile",
      "evidence_ids": [
        "ev_cdde459f87b81902",
        "ev_1c22ef1d4a6f0958"
      ],
      "refs": [
        "CWE-489",
        "CWE-530",
        "CWE-319"
      ]
    },
    {
      "id": "K-002",
      "domain": "K",
      "title": "Android exported components protected by permission",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-mobile",
      "evidence_ids": [
        "ev_385c21dd4cc2e520"
      ],
      "refs": [
        "CWE-926"
      ]
    },
    {
      "id": "K-003",
      "domain": "K",
      "title": "Android runtime storage and transport verified on emulator",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs runtime.android_package, a running emulator with the debuggable test build, and `pandaward test --profile local-runtime`",
      "adapter": "local-runtime"
    },
    {
      "id": "K-004",
      "domain": "K",
      "title": "Android app does not keep credentials in plain SharedPreferences or world-accessible storage",
      "method": "static",
      "status": "PASS",
      "reason": "check completed with no signal (android manifest, iOS plist and entitlements, mobile storage checks); PASS applies to this check only",
      "adapter": "builtin-mobile",
      "refs": [
        "CWE-312",
        "CWE-276"
      ]
    },
    {
      "id": "K-005",
      "domain": "K",
      "title": "Built APK manifest: not debuggable, no backup or cleartext, no unprotected exported components",
      "method": "external",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'apk' assets found in inventory (review this decision)",
      "adapter": "apktool",
      "refs": [
        "CWE-489",
        "CWE-926"
      ]
    },
    {
      "id": "L-001",
      "domain": "L",
      "title": "iOS App Transport Security does not allow arbitrary loads",
      "method": "static",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'ios' assets found in inventory (review this decision)",
      "adapter": "builtin-mobile",
      "refs": [
        "CWE-319"
      ]
    },
    {
      "id": "L-002",
      "domain": "L",
      "title": "iOS keychain and storage verified on simulator",
      "method": "runtime",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'ios' assets found in inventory (review this decision)",
      "adapter": "local-runtime"
    },
    {
      "id": "L-003",
      "domain": "L",
      "title": "iOS entitlements do not allow debugging outside debug builds",
      "method": "static",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'ios' assets found in inventory (review this decision)",
      "adapter": "builtin-mobile",
      "refs": [
        "CWE-489"
      ]
    },
    {
      "id": "L-004",
      "domain": "L",
      "title": "iOS credentials kept in the Keychain with a restrictive accessibility class, not in UserDefaults",
      "method": "static",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'ios' assets found in inventory (review this decision)",
      "adapter": "builtin-mobile",
      "refs": [
        "CWE-922",
        "CWE-312"
      ]
    },
    {
      "id": "M-001",
      "domain": "M",
      "title": "Passive DAST (ZAP baseline) against approved target",
      "method": "runtime",
      "status": "BLOCKED",
      "reason": "needs `pandaward test --profile staging-active` with an approved scope manifest and ZAP installed",
      "adapter": "zap"
    },
    {
      "id": "N-001",
      "domain": "N",
      "title": "Third-party GitHub Actions pinned to a full commit SHA",
      "method": "static",
      "status": "FAIL",
      "reason": "2 confirmed observation(s)",
      "adapter": "builtin-cicd",
      "evidence_ids": [
        "ev_4611c27259ceb153",
        "ev_b013c649d18f6fc3"
      ],
      "refs": [
        "CWE-829"
      ]
    },
    {
      "id": "N-002",
      "domain": "N",
      "title": "No untrusted event data interpolated into run: scripts",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-cicd",
      "evidence_ids": [
        "ev_d4c0b7d0aaff8778"
      ],
      "refs": [
        "CWE-78"
      ]
    },
    {
      "id": "N-003",
      "domain": "N",
      "title": "pull_request_target workflows do not check out untrusted PR code",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-cicd",
      "evidence_ids": [
        "ev_4a7f9c2c4be3bcdb"
      ],
      "refs": [
        "CWE-829"
      ]
    },
    {
      "id": "N-004",
      "domain": "N",
      "title": "Workflow GITHUB_TOKEN permissions declared explicitly",
      "method": "static",
      "status": "FAIL",
      "reason": "1 confirmed observation(s)",
      "adapter": "builtin-cicd",
      "evidence_ids": [
        "ev_bc44fe7969b08ac8"
      ],
      "refs": [
        "CWE-250"
      ]
    },
    {
      "id": "O-001",
      "domain": "O",
      "title": "Security events logged and alerted (privilege changes, auth failures)",
      "method": "manual",
      "status": "BLOCKED",
      "reason": "manual-assisted review required (/pandaward:review); not decided by automation"
    },
    {
      "id": "O-002",
      "domain": "O",
      "title": "Secrets and credentials not written to logs",
      "method": "static",
      "status": "PASS",
      "reason": "check completed with no signal (code heuristics); PASS applies to this check only",
      "adapter": "builtin-code",
      "refs": [
        "CWE-532"
      ]
    },
    {
      "id": "P-001",
      "domain": "P",
      "title": "Model output is not executed as code or shell",
      "method": "static",
      "status": "SUSPECTED",
      "reason": "1 heuristic signal(s) need review; not confirmed",
      "adapter": "builtin-code",
      "evidence_ids": [
        "ev_f6f8776e80a54556"
      ],
      "refs": [
        "CWE-94"
      ]
    },
    {
      "id": "P-002",
      "domain": "P",
      "title": "MCP server configs pinned and free of inline credentials",
      "method": "static",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'mcp_config' assets found in inventory (review this decision)",
      "adapter": "builtin-supply",
      "refs": [
        "CWE-829",
        "CWE-798"
      ]
    },
    {
      "id": "P-003",
      "domain": "P",
      "title": "Prompt-injection and tool-authorization cases tested",
      "method": "runtime",
      "status": "UNSUPPORTED",
      "reason": "runtime adapter for profile staging-active is not implemented in this release; use manual-assisted review"
    },
    {
      "id": "Q-001",
      "domain": "Q",
      "title": "Rate limiting applied to authentication and expensive routes",
      "method": "manual",
      "status": "BLOCKED",
      "reason": "manual-assisted review required (/pandaward:review); not decided by automation",
      "refs": [
        "API4:2023",
        "CWE-770"
      ]
    },
    {
      "id": "Q-002",
      "domain": "Q",
      "title": "Concurrency and duplicate-action tests on stateful flows",
      "method": "runtime",
      "status": "UNSUPPORTED",
      "reason": "runtime adapter for profile staging-active is not implemented in this release; use manual-assisted review",
      "refs": [
        "CWE-362"
      ]
    },
    {
      "id": "R-001",
      "domain": "R",
      "title": "All evidence artifacts of this assessment verify against recorded SHA-256",
      "method": "static",
      "status": "PASS",
      "reason": "31 evidence artifacts verified against SHA-256",
      "adapter": "builtin-evidence"
    },
    {
      "id": "R-002",
      "domain": "R",
      "title": "Imported third-party analyzer results (SARIF) report no findings",
      "method": "external",
      "status": "NOT_APPLICABLE",
      "reason": "auto: no 'sarif' assets found in inventory (review this decision)",
      "adapter": "sarif-import"
    }
  ],
  "edges": [
    {
      "id": "AB1",
      "domains": "AB",
      "title": "Discovered login endpoints -\u003e session tests",
      "scenario": "New auth route missing token/session coverage",
      "status": "BLOCKED",
      "reason": "not decided: A-002=INCONCLUSIVE, B-003=UNSUPPORTED, B-004=BLOCKED",
      "provenance": [
        "route:POST:/api/login@src/server.js"
      ],
      "tests": [
        "A-002",
        "B-003",
        "B-004"
      ]
    },
    {
      "id": "AC1",
      "domains": "AC",
      "title": "Asset owners -\u003e access policies",
      "scenario": "Orphan routes lack authorization checks",
      "status": "BLOCKED",
      "reason": "not decided: C-002=BLOCKED, C-003=BLOCKED",
      "provenance": [
        "route:POST:/api/login@src/server.js",
        "route:GET:/api/invoices/:id@src/server.js",
        "route:POST:/webhooks/stripe@src/server.js",
        "route:GET:/admin/run@src/server.js"
      ],
      "tests": [
        "C-002",
        "C-003"
      ]
    },
    {
      "id": "AD1",
      "domains": "AD",
      "title": "Input entrypoints -\u003e sinks",
      "scenario": "Ingress path crosses a parsing or command boundary",
      "status": "FAIL",
      "reason": "failed controls: D-001, D-002",
      "provenance": [
        "control:D-001",
        "control:D-002",
        "control:D-003",
        "control:D-004",
        "file:src/server.js"
      ],
      "tests": [
        "D-001",
        "D-002",
        "D-003",
        "D-004",
        "D-005"
      ]
    },
    {
      "id": "AE1",
      "domains": "AE",
      "title": "Asset classification -\u003e secret scan",
      "scenario": "Secret material flows into config, workflow or IaC",
      "status": "FAIL",
      "reason": "failed controls: E-001, E-002",
      "provenance": [
        "control:E-001",
        "control:E-002"
      ],
      "tests": [
        "E-001",
        "E-002"
      ]
    },
    {
      "id": "AG1",
      "domains": "AG",
      "title": "Service inventory -\u003e API coverage",
      "scenario": "Undocumented endpoints bypass contract tests",
      "status": "BLOCKED",
      "reason": "not decided: G-002=UNSUPPORTED",
      "provenance": [
        "openapi.yaml",
        "route:POST:/api/login@src/server.js",
        "route:GET:/api/invoices/:id@src/server.js",
        "route:POST:/webhooks/stripe@src/server.js",
        "route:GET:/admin/run@src/server.js"
      ],
      "tests": [
        "A-003",
        "G-002"
      ]
    },
    {
      "id": "AJ1",
      "domains": "AJ",
      "title": "Cloud-deployed asset -\u003e exposure",
      "scenario": "Private API exposed by ingress or policy drift",
      "status": "FAIL",
      "reason": "failed controls: J-001, J-004",
      "provenance": [
        "route:POST:/api/login@src/server.js",
        "route:GET:/api/invoices/:id@src/server.js",
        "route:POST:/webhooks/stripe@src/server.js",
        "route:GET:/admin/run@src/server.js",
        "Dockerfile",
        "infra/main.tf"
      ],
      "tests": [
        "J-001",
        "J-003",
        "J-004"
      ]
    },
    {
      "id": "BC1",
      "domains": "BC",
      "title": "Authenticated identity -\u003e authorization",
      "scenario": "Valid user can access another tenant's object",
      "status": "BLOCKED",
      "reason": "not decided: C-001=BLOCKED",
      "provenance": [
        "route:POST:/api/login@src/server.js",
        "route:GET:/api/invoices/:id@src/server.js"
      ],
      "tests": [
        "C-001"
      ]
    },
    {
      "id": "BK1",
      "domains": "BK",
      "title": "Mobile identity -\u003e Android storage",
      "scenario": "Token copied to Android insecure storage",
      "status": "FAIL",
      "reason": "failed controls: K-001",
      "provenance": [
        "android/app/src/main/AndroidManifest.xml",
        "src/server.js",
        "route:POST:/api/login@src/server.js"
      ],
      "tests": [
        "K-001",
        "K-003"
      ]
    },
    {
      "id": "CG1",
      "domains": "CG",
      "title": "Object access -\u003e API response",
      "scenario": "Mass assignment or property-level data access",
      "status": "BLOCKED",
      "reason": "not decided: C-001=BLOCKED, G-002=UNSUPPORTED",
      "provenance": [
        "route:GET:/api/invoices/:id@src/server.js"
      ],
      "tests": [
        "C-001",
        "G-002"
      ]
    },
    {
      "id": "DG1",
      "domains": "DG",
      "title": "Webhook input -\u003e API trust",
      "scenario": "Unsigned callback payload drives privileged state",
      "status": "SUSPECTED",
      "reason": "suspected: G-001",
      "provenance": [
        "route:POST:/webhooks/stripe@src/server.js"
      ],
      "tests": [
        "G-001"
      ]
    },
    {
      "id": "DH1",
      "domains": "DH",
      "title": "HTML output -\u003e browser",
      "scenario": "Unescaped backend content reaches the DOM",
      "status": "SUSPECTED",
      "reason": "suspected: H-001",
      "provenance": [
        "control:H-001"
      ],
      "tests": [
        "H-001"
      ]
    },
    {
      "id": "DP1",
      "domains": "DP",
      "title": "Prompt content -\u003e tools",
      "scenario": "Untrusted retrieved text triggers a tool action",
      "status": "BLOCKED",
      "reason": "not decided: P-003=UNSUPPORTED",
      "provenance": [
        "app.py"
      ],
      "tests": [
        "P-001",
        "P-003"
      ]
    },
    {
      "id": "FG1",
      "domains": "FG",
      "title": "Payment state -\u003e webhooks",
      "scenario": "Replay moves payment into an invalid terminal state",
      "status": "BLOCKED",
      "reason": "not decided: F-001=BLOCKED",
      "provenance": [
        "src/server.js",
        "route:POST:/webhooks/stripe@src/server.js"
      ],
      "tests": [
        "F-001",
        "G-001"
      ]
    },
    {
      "id": "FQ1",
      "domains": "FQ",
      "title": "State machine -\u003e race",
      "scenario": "Concurrent requests bypass idempotency",
      "status": "BLOCKED",
      "reason": "not decided: F-002=UNSUPPORTED, Q-002=UNSUPPORTED",
      "provenance": [
        "src/server.js"
      ],
      "tests": [
        "F-002",
        "Q-002"
      ]
    },
    {
      "id": "IN1",
      "domains": "IN",
      "title": "Action dependency -\u003e CI integrity",
      "scenario": "Unpinned third-party action may change code",
      "status": "FAIL",
      "reason": "failed controls: N-001",
      "provenance": [
        ".github/workflows/ci.yml"
      ],
      "tests": [
        "N-001"
      ]
    }
  ],
  "findings": [
    {
      "id": "PW-0022",
      "fingerprint": "b7653391b226aa9e529fcd3857b8dbbb",
      "rule_id": "cicd.prt-untrusted-checkout",
      "control_id": "N-003",
      "title": "pull_request_target checks out untrusted PR code",
      "severity": "critical",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-829",
      "file": ".github/workflows/ci.yml",
      "start_line": 8,
      "end_line": 8,
      "message": "pull_request_target runs with repository secrets and a write token; checking out the PR head lets any fork author run code with them.",
      "fix": "Use pull_request for building untrusted code, or split into an unprivileged build and a privileged workflow_run that only consumes artifacts.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-cicd completes and no longer observes it.",
      "collector": "builtin-cicd",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_4a7f9c2c4be3bcdb"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0004",
      "fingerprint": "7f82aafcfb4623fe7396f6f50fe55e43",
      "rule_id": "secret.github-token",
      "control_id": "E-001",
      "title": "Hardcoded GitHub token",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-798",
      "file": "app.py",
      "start_line": 8,
      "end_line": 8,
      "message": "A value matching the GitHub token format is stored in the repository. The value is masked in all Pandaward output.",
      "fix": "Revoke and rotate the credential at the provider first, then remove it from the code and git history; load it from a secret manager or environment at runtime.",
      "retest": "Re-run `pandaward scan`; also verify with the provider that the old credential is revoked.",
      "collector": "builtin-secrets",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_4fc7c8c69e031156"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0005",
      "fingerprint": "59d891e701e80ff28c6fee51aa4a87ee",
      "rule_id": "secret.stripe-live-key",
      "control_id": "E-001",
      "title": "Hardcoded Stripe live secret key",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-798",
      "file": "src/server.js",
      "start_line": 2,
      "end_line": 2,
      "message": "A value matching the Stripe live secret key format is stored in the repository. The value is masked in all Pandaward output.",
      "fix": "Revoke and rotate the credential at the provider first, then remove it from the code and git history; load it from a secret manager or environment at runtime.",
      "retest": "Re-run `pandaward scan`; also verify with the provider that the old credential is revoked.",
      "collector": "builtin-secrets",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_17b39394ce37dd0a"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0006",
      "fingerprint": "66d9729f109f7130acf278db34354732",
      "rule_id": "secret.tracked-sensitive-file",
      "control_id": "E-002",
      "title": "Credential or environment file tracked in git",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-538",
      "file": ".env",
      "message": "This file type usually holds credentials and is committed to git. Pandaward did not read its content.",
      "fix": "Rotate any credentials it contains, `git rm --cached` it, add it to .gitignore, and purge it from history if the repository is shared.",
      "retest": "Re-run `pandaward scan`; the file must no longer be tracked.",
      "collector": "builtin-secrets",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_2b3c5175a0b4065c"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0008",
      "fingerprint": "030ecb81ed196a18e92b7793303d51c1",
      "rule_id": "code.tls-verify-off",
      "control_id": "E-003",
      "title": "TLS certificate verification disabled",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-295",
      "file": "app.py",
      "start_line": 5,
      "end_line": 5,
      "message": "Certificate verification is turned off, so any network attacker can impersonate the server.",
      "fix": "Remove the override; trust a specific CA bundle if a private CA is needed.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_e8d11c07675dc9ab"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0009",
      "fingerprint": "6f22338a1325b13f7bffa3aa4dc821da",
      "rule_id": "code.py-shell",
      "control_id": "D-002",
      "title": "Shell command execution",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-78",
      "file": "app.py",
      "start_line": 6,
      "end_line": 6,
      "message": "Command runs through a shell interpreter.",
      "fix": "Use subprocess.run([...], shell=False) with an argument list.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_94913aefcc6346ee"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0010",
      "fingerprint": "31ad406a6b94a84d38345fe14dad567b",
      "rule_id": "code.py-eval",
      "control_id": "D-001",
      "title": "Dynamic code evaluation",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-95",
      "file": "app.py",
      "start_line": 7,
      "end_line": 7,
      "message": "eval/exec evaluates strings as Python code.",
      "fix": "Use ast.literal_eval for literals or explicit parsing; never eval input.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_a9c4d034c668acc8"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0014",
      "fingerprint": "b6c23363b5fa6a4f632509c880947aab",
      "rule_id": "code.js-eval",
      "control_id": "D-001",
      "title": "Dynamic code evaluation",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-95",
      "file": "src/server.js",
      "start_line": 8,
      "end_line": 8,
      "message": "Strings are evaluated as code. If any part of the string can be influenced by a user, this is code injection.",
      "fix": "Replace eval/new Function with explicit parsing or a lookup table; never evaluate strings.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_7eb1da32ab0560fe"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0017",
      "fingerprint": "2d898194c74466bfb1969b171f1c8844",
      "rule_id": "code.cors-wildcard-credentials",
      "control_id": "H-002",
      "title": "CORS allows any origin with credentials",
      "severity": "high",
      "confidence": "STRONGLY_SUPPORTED",
      "status": "OPEN",
      "cwe": "CWE-942",
      "file": "src/server.js",
      "start_line": 4,
      "end_line": 4,
      "message": "Any origin (or a reflected origin) is allowed together with credentials, so other sites can make authenticated reads.",
      "fix": "Use an explicit allowlist of trusted origins when credentials are enabled.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_8f75c59732ca936d"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0021",
      "fingerprint": "5976f8ef5cf915889203da0a1d9808f6",
      "rule_id": "cicd.script-injection",
      "control_id": "N-002",
      "title": "Untrusted event data interpolated into a run script",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-78",
      "file": ".github/workflows/ci.yml",
      "start_line": 11,
      "end_line": 11,
      "message": "Attacker-controlled text (titles, bodies, branch names) is expanded into the shell script before it runs, allowing command injection in CI.",
      "fix": "Pass the value through an environment variable (env: TITLE: ${{ ... }}) and reference \"$TITLE\" in the script.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-cicd completes and no longer observes it.",
      "collector": "builtin-cicd",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_d4c0b7d0aaff8778"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0026",
      "fingerprint": "ae76d8ec7a72faad239671b1143e8822",
      "rule_id": "infra.public-storage",
      "control_id": "J-004",
      "title": "Public storage or database exposure",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-284",
      "file": "infra/main.tf",
      "start_line": 1,
      "end_line": 1,
      "message": "The resource is configured for public access.",
      "fix": "Keep storage and databases private; serve public files through a CDN with explicit, read-only policy.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-infra completes and no longer observes it.",
      "collector": "builtin-infra",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_4f9bf0d255e934f1"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0027",
      "fingerprint": "bb9ccc6bcb48198e74caf14c75812acb",
      "rule_id": "infra.world-open-admin-port",
      "control_id": "J-004",
      "title": "Administrative or database port open to the internet",
      "severity": "high",
      "confidence": "STRONGLY_SUPPORTED",
      "status": "OPEN",
      "cwe": "CWE-284",
      "file": "infra/main.tf",
      "start_line": 6,
      "end_line": 6,
      "message": "A security group/firewall rule allows 0.0.0.0/0 near an SSH, RDP or database port.",
      "fix": "Restrict the source to a VPN/bastion range or use a managed access proxy.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-infra completes and no longer observes it.",
      "collector": "builtin-infra",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_822dc4e9c892428a"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0029",
      "fingerprint": "483cf291607cbeae5cfe2b10efd9fc95",
      "rule_id": "mobile.android-debuggable",
      "control_id": "K-001",
      "title": "Android app is debuggable",
      "severity": "high",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-489",
      "file": "android/app/src/main/AndroidManifest.xml",
      "start_line": 1,
      "end_line": 1,
      "message": "Manifest sets android:debuggable=\"true\". Static observation; runtime impact depends on build variant.",
      "fix": "Set android:debuggable to false for release builds (use build-type manifest placeholders).",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-mobile completes and no longer observes it.",
      "collector": "builtin-mobile",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_cdde459f87b81902"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0020",
      "fingerprint": "3c4a9e008e3fa49f0709aff48af1d3bb",
      "rule_id": "cicd.unpinned-action",
      "control_id": "N-001",
      "title": "GitHub Action not pinned to a commit SHA",
      "severity": "medium",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-829",
      "file": ".github/workflows/ci.yml",
      "start_line": 9,
      "end_line": 9,
      "message": "someone/deploy-action@main uses a mutable reference; whoever controls that tag/branch can change the code that runs with this workflow's secrets.",
      "fix": "Pin to the full 40-character commit SHA of a reviewed release and keep the version in a trailing comment; let Dependabot/Renovate update it.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-cicd completes and no longer observes it.",
      "collector": "builtin-cicd",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_b013c649d18f6fc3"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0023",
      "fingerprint": "cacf91233296fbafae61a90c79cf2be9",
      "rule_id": "cicd.no-permissions",
      "control_id": "N-004",
      "title": "Workflow does not declare GITHUB_TOKEN permissions",
      "severity": "medium",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-250",
      "file": ".github/workflows/ci.yml",
      "start_line": 1,
      "end_line": 1,
      "message": "Without a permissions block the token gets the repository default, which may be read-write for everything.",
      "fix": "Add `permissions: contents: read` at the top level and grant extra scopes per job only where needed.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-cicd completes and no longer observes it.",
      "collector": "builtin-cicd",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_bc44fe7969b08ac8"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0025",
      "fingerprint": "698fdb7245a3c93b5db8b00e02bbd741",
      "rule_id": "infra.container-root",
      "control_id": "J-001",
      "title": "Container runs as root",
      "severity": "medium",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-250",
      "file": "Dockerfile",
      "start_line": 1,
      "end_line": 1,
      "message": "The final image stage has no non-root USER, so a compromise of the process is root inside the container.",
      "fix": "Create an unprivileged user and add `USER \u003cuid\u003e` in the final stage.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-infra completes and no longer observes it.",
      "collector": "builtin-infra",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_2dd232b952152e08"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0028",
      "fingerprint": "43986475f31adf4f3beef4ca1e0f33a1",
      "rule_id": "supply.missing-lockfile",
      "control_id": "I-001",
      "title": "Package manifest without lockfile",
      "severity": "medium",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-829",
      "file": "package.json",
      "start_line": 1,
      "end_line": 1,
      "message": "Without a committed lockfile every install can resolve different transitive versions, including a newly published malicious one.",
      "fix": "Commit the lockfile and install with the frozen/ci mode (npm ci, pip install --require-hashes, go mod verify).",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-supply completes and no longer observes it.",
      "collector": "builtin-supply",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_e081c5b1020366d9"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0019",
      "fingerprint": "ce0b8ecb7f7e5310cde52edf349a0780",
      "rule_id": "cicd.unpinned-action",
      "control_id": "N-001",
      "title": "GitHub Action not pinned to a commit SHA",
      "severity": "low",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-829",
      "file": ".github/workflows/ci.yml",
      "start_line": 6,
      "end_line": 6,
      "message": "actions/checkout@v4 uses a mutable reference; whoever controls that tag/branch can change the code that runs with this workflow's secrets.",
      "fix": "Pin to the full 40-character commit SHA of a reviewed release and keep the version in a trailing comment; let Dependabot/Renovate update it.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-cicd completes and no longer observes it.",
      "collector": "builtin-cicd",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_4611c27259ceb153"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0024",
      "fingerprint": "874113bedb319c126fa2cc86a308317d",
      "rule_id": "infra.unpinned-base-image",
      "control_id": "J-002",
      "title": "Base image not pinned",
      "severity": "low",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-829",
      "file": "Dockerfile",
      "start_line": 1,
      "end_line": 1,
      "message": "The base image uses latest or no tag, so builds are not reproducible and can silently pick up a changed image.",
      "fix": "Pin a specific version tag, ideally with @sha256 digest, and update it deliberately.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-infra completes and no longer observes it.",
      "collector": "builtin-infra",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_98bb7a66c22d7481"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0030",
      "fingerprint": "5812e3e05dc12ad60a25a7c60fd62576",
      "rule_id": "mobile.android-allow-backup",
      "control_id": "K-001",
      "title": "Android backup enabled",
      "severity": "low",
      "confidence": "CONFIRMED",
      "status": "OPEN",
      "cwe": "CWE-530",
      "file": "android/app/src/main/AndroidManifest.xml",
      "start_line": 1,
      "end_line": 1,
      "message": "Manifest sets android:allowBackup=\"true\". Static observation; runtime impact depends on build variant.",
      "fix": "Set android:allowBackup to false for release builds (use build-type manifest placeholders).",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-mobile completes and no longer observes it.",
      "collector": "builtin-mobile",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_1c22ef1d4a6f0958"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0007",
      "fingerprint": "65a10cb35d42416ffb395746af63e104",
      "rule_id": "code.py-deserialize",
      "control_id": "D-004",
      "title": "Unsafe deserialization API",
      "severity": "high",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-502",
      "file": "app.py",
      "start_line": 4,
      "end_line": 4,
      "message": "Deserializing untrusted data with this API can execute code.",
      "fix": "Use JSON or yaml.safe_load; never unpickle data from outside the trust boundary.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_45edd1ca1b90d972"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0011",
      "fingerprint": "94d9872aabd132672bbdc48fffbdaa86",
      "rule_id": "code.llm-output-exec",
      "control_id": "P-001",
      "title": "Model output may reach code or shell execution",
      "severity": "high",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-94",
      "file": "app.py",
      "start_line": 7,
      "end_line": 7,
      "message": "An execution sink appears on the same line as model output. Prompt injection could turn into code execution.",
      "fix": "Treat model output as untrusted data: parse into a typed structure, validate against an allowlist, require human approval for side effects.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_f6f8776e80a54556"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0013",
      "fingerprint": "f23a1dd6b00a74d0d98a7e074004c66c",
      "rule_id": "code.sql-concat",
      "control_id": "D-003",
      "title": "SQL built with string concatenation",
      "severity": "high",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-89",
      "file": "src/server.js",
      "start_line": 6,
      "end_line": 6,
      "message": "Query text is concatenated with values; if a value is user controlled this is SQL injection.",
      "fix": "Use parameterized queries / prepared statements or the ORM query builder.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_9163cd2dde765988"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0015",
      "fingerprint": "1bb2b4d254656348b477785252b7af42",
      "rule_id": "code.js-shell",
      "control_id": "D-002",
      "title": "Shell command built from a string",
      "severity": "high",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-78",
      "file": "src/server.js",
      "start_line": 8,
      "end_line": 8,
      "message": "child_process.exec or shell:true runs the command through a shell; interpolated values allow command injection.",
      "fix": "Use execFile/spawn with an argument array and shell:false; validate arguments against an allowlist.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_18bcf670b9fe88b6"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0018",
      "fingerprint": "62f3985434aef3507d11e334dffeb946",
      "rule_id": "code.webhook-no-signature",
      "control_id": "G-001",
      "title": "Webhook handler without visible signature verification",
      "severity": "high",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-345",
      "file": "src/server.js",
      "start_line": 7,
      "end_line": 7,
      "message": "No signature/HMAC verification was found in the file that defines this webhook route. Verification may live in middleware; confirm manually.",
      "fix": "Verify the provider signature over the raw request body with a constant-time compare before parsing or acting; reject replays by timestamp/event ID.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_fdf34989adaac10f"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0001",
      "fingerprint": "e799873a33048e0d729f3526ac12562c",
      "rule_id": "inventory.undeclared-route",
      "control_id": "A-003",
      "title": "Route not declared in the OpenAPI contract",
      "severity": "medium",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "file": "src/server.js",
      "start_line": 8,
      "end_line": 8,
      "message": "GET /admin/run is implemented but not documented; undocumented endpoints often miss contract and authorization tests (shadow API).",
      "fix": "Document the endpoint in the OpenAPI contract with its security requirements, or remove it if unused.",
      "retest": "Re-run `pandaward scan`; the route must appear in the contract comparison.",
      "collector": "builtin-inventory",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_efa0768a93861314"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0002",
      "fingerprint": "23965c76a10c9375bd7f1b8ca22449f3",
      "rule_id": "inventory.undeclared-route",
      "control_id": "A-003",
      "title": "Route not declared in the OpenAPI contract",
      "severity": "medium",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "file": "src/server.js",
      "start_line": 6,
      "end_line": 6,
      "message": "GET /api/invoices/:id is implemented but not documented; undocumented endpoints often miss contract and authorization tests (shadow API).",
      "fix": "Document the endpoint in the OpenAPI contract with its security requirements, or remove it if unused.",
      "retest": "Re-run `pandaward scan`; the route must appear in the contract comparison.",
      "collector": "builtin-inventory",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_47d3f7f67228fdd6"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0003",
      "fingerprint": "3b8f341fb9356a1b4169144abedfaf74",
      "rule_id": "inventory.undeclared-route",
      "control_id": "A-003",
      "title": "Route not declared in the OpenAPI contract",
      "severity": "medium",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "file": "src/server.js",
      "start_line": 7,
      "end_line": 7,
      "message": "POST /webhooks/stripe is implemented but not documented; undocumented endpoints often miss contract and authorization tests (shadow API).",
      "fix": "Document the endpoint in the OpenAPI contract with its security requirements, or remove it if unused.",
      "retest": "Re-run `pandaward scan`; the route must appear in the contract comparison.",
      "collector": "builtin-inventory",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_2de440fb1038ae7e"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0012",
      "fingerprint": "e51ee053008fbd6413a914fcdc764965",
      "rule_id": "code.jwt-decode-no-verify",
      "control_id": "B-001",
      "title": "jwt.decode used (no signature check)",
      "severity": "medium",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-347",
      "file": "src/server.js",
      "start_line": 5,
      "end_line": 5,
      "message": "jsonwebtoken's decode() does not verify the signature; trusting its output for authorization is unsafe.",
      "fix": "Use jwt.verify(token, key, { algorithms: [...] }) for anything security relevant.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_ba4887d7098ce9c5"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0016",
      "fingerprint": "3a68ea8376b56e9779167dbc4e66da29",
      "rule_id": "code.html-sink",
      "control_id": "H-001",
      "title": "Raw HTML sink",
      "severity": "medium",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-79",
      "file": "src/server.js",
      "start_line": 9,
      "end_line": 9,
      "message": "Content is inserted as raw HTML. If it can contain user data this is cross-site scripting.",
      "fix": "Render as text, or sanitize with a maintained sanitizer (DOMPurify) right at the sink.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-code completes and no longer observes it.",
      "collector": "builtin-code",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_3492a3599d7b8d70"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    },
    {
      "id": "PW-0031",
      "fingerprint": "8830e25bc7ef12dcb0fb5f4edd587cdc",
      "rule_id": "mobile.android-exported-component",
      "control_id": "K-002",
      "title": "Exported Android component without permission",
      "severity": "medium",
      "confidence": "HYPOTHESIS",
      "status": "OPEN",
      "cwe": "CWE-926",
      "file": "android/app/src/main/AndroidManifest.xml",
      "start_line": 3,
      "end_line": 3,
      "message": "Any installed app can invoke this receiver. Confirm it validates callers and input.",
      "fix": "Set android:exported=\"false\" unless required, or protect it with a signature-level permission.",
      "retest": "Apply the fix, then run `pandaward retest`; the finding becomes REMEDIATED only when builtin-mobile completes and no longer observes it.",
      "collector": "builtin-mobile",
      "first_seen": "2026-10-28T20:49:03Z",
      "last_seen": "2026-10-28T20:49:03Z",
      "evidence_ids": [
        "ev_385c21dd4cc2e520"
      ],
      "assessment_id": "asmt_0001_20261028T204903Z"
    }
  ],
  "runs": [
    {
      "id": "builtin-cicd-20261028T204903.244Z",
      "adapter": "builtin-cicd",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "1 workflows",
      "signals": 5
    },
    {
      "id": "builtin-code-20261028T204903.242Z",
      "adapter": "builtin-code",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "code heuristics",
      "signals": 12
    },
    {
      "id": "builtin-infra-20261028T204903.244Z",
      "adapter": "builtin-infra",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "dockerfile/compose/k8s/terraform checks",
      "signals": 4
    },
    {
      "id": "builtin-inventory-20261028T204903.241Z",
      "adapter": "builtin-inventory",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "15 assets",
      "signals": 3
    },
    {
      "id": "builtin-mobile-20261028T204903.245Z",
      "adapter": "builtin-mobile",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "android manifest, iOS plist and entitlements, mobile storage checks",
      "signals": 3
    },
    {
      "id": "builtin-secrets-20261028T204903.241Z",
      "adapter": "builtin-secrets",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "16 secret formats checked; 1 sensitive file names recorded without reading",
      "signals": 3
    },
    {
      "id": "builtin-supply-20261028T204903.244Z",
      "adapter": "builtin-supply",
      "tool_version": "0.2.1",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "OK",
      "detail": "lockfiles, install scripts, requirement pins, MCP configs",
      "signals": 1
    },
    {
      "id": "gitleaks-20261028T204903.245Z",
      "adapter": "gitleaks",
      "tool_version": "",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "BLOCKED",
      "detail": "gitleaks is not installed (optional; run `pandaward doctor`)",
      "signals": 0
    },
    {
      "id": "osv-scanner-20261028T204903.245Z",
      "adapter": "osv-scanner",
      "tool_version": "",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "BLOCKED",
      "detail": "osv-scanner is not installed (optional; run `pandaward doctor`)",
      "signals": 0
    },
    {
      "id": "semgrep-20261028T204903.245Z",
      "adapter": "semgrep",
      "tool_version": "",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "BLOCKED",
      "detail": "semgrep is not installed (optional; run `pandaward doctor`)",
      "signals": 0
    },
    {
      "id": "trivy-20261028T204903.245Z",
      "adapter": "trivy",
      "tool_version": "",
      "started_at": "2026-10-28T20:49:03Z",
      "ended_at": "2026-10-28T20:49:03Z",
      "exit_class": "BLOCKED",
      "detail": "trivy is not installed (optional; run `pandaward doctor`)",
      "signals": 0
    }
  ],
  "evidence_index": [
    {
      "id": "ev_17b39394ce37dd0a",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "17b39394ce37dd0a0de700dbb903572efdc354be838155d54c2c8d0e2efeb0b8",
      "path": "17b39394ce37dd0a0de700dbb903572efdc354be838155d54c2c8d0e2efeb0b8.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-secrets",
      "source_ref": "src/server.js#L2-L2"
    },
    {
      "id": "ev_18bcf670b9fe88b6",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "18bcf670b9fe88b64d139efde10e65e0274fd3ea4a73c2a93e2c4a572da8695c",
      "path": "18bcf670b9fe88b64d139efde10e65e0274fd3ea4a73c2a93e2c4a572da8695c.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L8-L8"
    },
    {
      "id": "ev_1c22ef1d4a6f0958",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "1c22ef1d4a6f09581363dd3d521b89f576fca9e2b7bb6e7726d2f7f3b454df37",
      "path": "1c22ef1d4a6f09581363dd3d521b89f576fca9e2b7bb6e7726d2f7f3b454df37.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-mobile",
      "source_ref": "android/app/src/main/AndroidManifest.xml#L1-L1"
    },
    {
      "id": "ev_2b3c5175a0b4065c",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "2b3c5175a0b4065c3599ce12d8dba7960e6c5b9bd6c16c3947e367598bbbd094",
      "path": "2b3c5175a0b4065c3599ce12d8dba7960e6c5b9bd6c16c3947e367598bbbd094.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-secrets",
      "source_ref": ".env"
    },
    {
      "id": "ev_2dd232b952152e08",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "2dd232b952152e08f1ef75802cc28bd5c6a074299101c0cb03b2cf1b68185a6a",
      "path": "2dd232b952152e08f1ef75802cc28bd5c6a074299101c0cb03b2cf1b68185a6a.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-infra",
      "source_ref": "Dockerfile#L1-L1"
    },
    {
      "id": "ev_2de440fb1038ae7e",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "2de440fb1038ae7e66d537bbf6b430507479cf5d1ce6519a58c423374907823d",
      "path": "2de440fb1038ae7e66d537bbf6b430507479cf5d1ce6519a58c423374907823d.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-inventory",
      "source_ref": "src/server.js#L7-L7"
    },
    {
      "id": "ev_3492a3599d7b8d70",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "3492a3599d7b8d7016a07bcb9ed0773f888387f2c95f9d77d8e6ca53c4012d5d",
      "path": "3492a3599d7b8d7016a07bcb9ed0773f888387f2c95f9d77d8e6ca53c4012d5d.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L9-L9"
    },
    {
      "id": "ev_385c21dd4cc2e520",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "385c21dd4cc2e520f0876003cd58591eaffa08d917771aca8bace033edbe4a72",
      "path": "385c21dd4cc2e520f0876003cd58591eaffa08d917771aca8bace033edbe4a72.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-mobile",
      "source_ref": "android/app/src/main/AndroidManifest.xml#L3-L3"
    },
    {
      "id": "ev_45edd1ca1b90d972",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "45edd1ca1b90d972b8b85cde1a248bcffb06f92e712dda6b36da2a3d7fc9fce5",
      "path": "45edd1ca1b90d972b8b85cde1a248bcffb06f92e712dda6b36da2a3d7fc9fce5.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "app.py#L4-L4"
    },
    {
      "id": "ev_4611c27259ceb153",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "4611c27259ceb1535e0118b38d6fcd0380e333979e1415875926554f10ca9f10",
      "path": "4611c27259ceb1535e0118b38d6fcd0380e333979e1415875926554f10ca9f10.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-cicd",
      "source_ref": ".github/workflows/ci.yml#L6-L6"
    },
    {
      "id": "ev_47d3f7f67228fdd6",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "47d3f7f67228fdd6afc263d85982473a7b4838a60bf30fa2fdbc3b75bf60a86e",
      "path": "47d3f7f67228fdd6afc263d85982473a7b4838a60bf30fa2fdbc3b75bf60a86e.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-inventory",
      "source_ref": "src/server.js#L6-L6"
    },
    {
      "id": "ev_4a7f9c2c4be3bcdb",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "4a7f9c2c4be3bcdb8687f118ec4015e3782a9ea4a7080672b281f92d07d6fa0a",
      "path": "4a7f9c2c4be3bcdb8687f118ec4015e3782a9ea4a7080672b281f92d07d6fa0a.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-cicd",
      "source_ref": ".github/workflows/ci.yml#L8-L8"
    },
    {
      "id": "ev_4f9bf0d255e934f1",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "4f9bf0d255e934f197e52ca274cb292eb831a90bd499a2021158cc82d14881ac",
      "path": "4f9bf0d255e934f197e52ca274cb292eb831a90bd499a2021158cc82d14881ac.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-infra",
      "source_ref": "infra/main.tf#L1-L1"
    },
    {
      "id": "ev_4fc7c8c69e031156",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "4fc7c8c69e031156263780edf79b4f52804e1991029f5388c4d6ab98516afcaa",
      "path": "4fc7c8c69e031156263780edf79b4f52804e1991029f5388c4d6ab98516afcaa.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-secrets",
      "source_ref": "app.py#L8-L8"
    },
    {
      "id": "ev_7eb1da32ab0560fe",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "7eb1da32ab0560fe2ee8962ada80f96dbe720e4c9aeedcadfd3dd40feef13daa",
      "path": "7eb1da32ab0560fe2ee8962ada80f96dbe720e4c9aeedcadfd3dd40feef13daa.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L8-L8"
    },
    {
      "id": "ev_822dc4e9c892428a",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "822dc4e9c892428aea1fa57990ff08b0f58ac5f189179141e81ae2d071516875",
      "path": "822dc4e9c892428aea1fa57990ff08b0f58ac5f189179141e81ae2d071516875.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-infra",
      "source_ref": "infra/main.tf#L6-L6"
    },
    {
      "id": "ev_8f75c59732ca936d",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "8f75c59732ca936db9fb6715c44a20e9772c50aceb3f8d022c970a5700bce04d",
      "path": "8f75c59732ca936db9fb6715c44a20e9772c50aceb3f8d022c970a5700bce04d.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L4-L4"
    },
    {
      "id": "ev_9163cd2dde765988",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "9163cd2dde7659880af78bc17e9b265ce83f9248557f2a54824be4725b7647a3",
      "path": "9163cd2dde7659880af78bc17e9b265ce83f9248557f2a54824be4725b7647a3.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L6-L6"
    },
    {
      "id": "ev_94913aefcc6346ee",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "94913aefcc6346ee4a0057bf92ee3bdaa7889ff39d20b3818bf17f30e656a4b7",
      "path": "94913aefcc6346ee4a0057bf92ee3bdaa7889ff39d20b3818bf17f30e656a4b7.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "app.py#L6-L6"
    },
    {
      "id": "ev_98bb7a66c22d7481",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "98bb7a66c22d7481eea003e7ec8b2dbabedd051499b73798d6e0f57e013ff363",
      "path": "98bb7a66c22d7481eea003e7ec8b2dbabedd051499b73798d6e0f57e013ff363.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-infra",
      "source_ref": "Dockerfile#L1-L1"
    },
    {
      "id": "ev_a9c4d034c668acc8",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "a9c4d034c668acc81cd7cdb434c4597d35e6d7568a4840db216326a061460f3f",
      "path": "a9c4d034c668acc81cd7cdb434c4597d35e6d7568a4840db216326a061460f3f.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "app.py#L7-L7"
    },
    {
      "id": "ev_b013c649d18f6fc3",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "b013c649d18f6fc37f8cefa1ea850deb9289169e1cfec887694e8ca51d5acbe1",
      "path": "b013c649d18f6fc37f8cefa1ea850deb9289169e1cfec887694e8ca51d5acbe1.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-cicd",
      "source_ref": ".github/workflows/ci.yml#L9-L9"
    },
    {
      "id": "ev_ba4887d7098ce9c5",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "ba4887d7098ce9c5f0d133ba772bbe0cf45b1ff2b3d2476df689e3571594bee8",
      "path": "ba4887d7098ce9c5f0d133ba772bbe0cf45b1ff2b3d2476df689e3571594bee8.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L5-L5"
    },
    {
      "id": "ev_bc44fe7969b08ac8",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "bc44fe7969b08ac86db054aafb4d26b89586d08b0546ef694b8cc58f309a1ff7",
      "path": "bc44fe7969b08ac86db054aafb4d26b89586d08b0546ef694b8cc58f309a1ff7.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-cicd",
      "source_ref": ".github/workflows/ci.yml#L1-L1"
    },
    {
      "id": "ev_cdde459f87b81902",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "cdde459f87b819027a96c9f7a2836db82d3d87d999df46fa3fe668c4097e3dfc",
      "path": "cdde459f87b819027a96c9f7a2836db82d3d87d999df46fa3fe668c4097e3dfc.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-mobile",
      "source_ref": "android/app/src/main/AndroidManifest.xml#L1-L1"
    },
    {
      "id": "ev_d4c0b7d0aaff8778",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "d4c0b7d0aaff8778b011b8b9a3db6440e2d144f22060290a326be3462e364fda",
      "path": "d4c0b7d0aaff8778b011b8b9a3db6440e2d144f22060290a326be3462e364fda.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-cicd",
      "source_ref": ".github/workflows/ci.yml#L11-L11"
    },
    {
      "id": "ev_e081c5b1020366d9",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "e081c5b1020366d9d14573e4fecfa24b1afacb3bc3f9b5a6472f6245d090d880",
      "path": "e081c5b1020366d9d14573e4fecfa24b1afacb3bc3f9b5a6472f6245d090d880.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-supply",
      "source_ref": "package.json#L1-L1"
    },
    {
      "id": "ev_e8d11c07675dc9ab",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "e8d11c07675dc9abaa9d111a717bdc9914443d8969b9f52ab584a747cec0060c",
      "path": "e8d11c07675dc9abaa9d111a717bdc9914443d8969b9f52ab584a747cec0060c.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "app.py#L5-L5"
    },
    {
      "id": "ev_efa0768a93861314",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "efa0768a9386131425422ebad65848b31fefd3a4d9265fab15f93834bc2f61cc",
      "path": "efa0768a9386131425422ebad65848b31fefd3a4d9265fab15f93834bc2f61cc.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-inventory",
      "source_ref": "src/server.js#L8-L8"
    },
    {
      "id": "ev_f6f8776e80a54556",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "f6f8776e80a545566da22965fa764a799f2401818a4b866cc32f2e26914b2a4a",
      "path": "f6f8776e80a545566da22965fa764a799f2401818a4b866cc32f2e26914b2a4a.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "app.py#L7-L7"
    },
    {
      "id": "ev_fdf34989adaac10f",
      "assessment_id": "asmt_0001_20261028T204903Z",
      "kind": "source-observation",
      "sha256": "fdf34989adaac10f800ab39fe8ed55cf4515004df04443de3800ab24a195cf02",
      "path": "fdf34989adaac10f800ab39fe8ed55cf4515004df04443de3800ab24a195cf02.json",
      "redaction_state": "REDACTED",
      "created_at": "2026-10-28T20:49:03Z",
      "collector": "builtin-code",
      "source_ref": "src/server.js#L7-L7"
    }
  ],
  "domains": [
    {
      "id": "A",
      "name": "Asset inventory, architecture and threat model"
    },
    {
      "id": "B",
      "name": "Authentication, sessions and identity"
    },
    {
      "id": "C",
      "name": "Authorization, roles and tenant isolation"
    },
    {
      "id": "D",
      "name": "Input, output, injection and data flow"
    },
    {
      "id": "E",
      "name": "Secrets, cryptography, privacy and storage"
    },
    {
      "id": "F",
      "name": "Business logic, integrity and financial workflows"
    },
    {
      "id": "G",
      "name": "API contracts, integrations and messaging"
    },
    {
      "id": "H",
      "name": "Web frontend, browser and client-side controls"
    },
    {
      "id": "I",
      "name": "Dependencies, SBOM and software supply chain"
    },
    {
      "id": "J",
      "name": "Cloud, infrastructure, network and IaC"
    },
    {
      "id": "K",
      "name": "Android application security"
    },
    {
      "id": "L",
      "name": "iOS application security"
    },
    {
      "id": "M",
      "name": "Dynamic application/API security testing"
    },
    {
      "id": "N",
      "name": "CI/CD, source control and release security"
    },
    {
      "id": "O",
      "name": "Observability, detection and recovery"
    },
    {
      "id": "P",
      "name": "AI/LLM, agents, prompts and MCP"
    },
    {
      "id": "Q",
      "name": "Availability, concurrency and abuse resistance"
    },
    {
      "id": "R",
      "name": "Reporting, governance and remediation assurance"
    }
  ],
  "domain_summary": {
    "A": {
      "BLOCKED": 1,
      "INCONCLUSIVE": 1,
      "PASS": 1,
      "SUSPECTED": 1
    },
    "B": {
      "BLOCKED": 1,
      "PASS": 1,
      "SUSPECTED": 1,
      "UNSUPPORTED": 1
    },
    "C": {
      "BLOCKED": 3
    },
    "D": {
      "BLOCKED": 2,
      "FAIL": 2,
      "SUSPECTED": 2
    },
    "E": {
      "BLOCKED": 1,
      "FAIL": 3,
      "PASS": 1
    },
    "F": {
      "BLOCKED": 1,
      "UNSUPPORTED": 1
    },
    "G": {
      "SUSPECTED": 1,
      "UNSUPPORTED": 1
    },
    "H": {
      "BLOCKED": 1,
      "SUSPECTED": 2
    },
    "I": {
      "BLOCKED": 1,
      "FAIL": 1,
      "NOT_APPLICABLE": 1,
      "PASS": 1
    },
    "J": {
      "BLOCKED": 1,
      "FAIL": 3,
      "NOT_APPLICABLE": 1
    },
    "K": {
      "BLOCKED": 1,
      "FAIL": 1,
      "NOT_APPLICABLE": 1,
      "PASS": 1,
      "SUSPECTED": 1
    },
    "L": {
      "NOT_APPLICABLE": 4
    },
    "M": {
      "BLOCKED": 1
    },
    "N": {
      "FAIL": 4
    },
    "O": {
      "BLOCKED": 1,
      "PASS": 1
    },
    "P": {
      "NOT_APPLICABLE": 1,
      "SUSPECTED": 1,
      "UNSUPPORTED": 1
    },
    "Q": {
      "BLOCKED": 1,
      "UNSUPPORTED": 1
    },
    "R": {
      "NOT_APPLICABLE": 1,
      "PASS": 1
    }
  },
  "assessment_manifest": {
    "catalog_version": "2026.10-m4",
    "config_sha256": "95839c1b2db37ed1cb4282275417cb7f3ddd51fa11bf60dcf5f748f7c5765260",
    "files_analyzed": 9,
    "files_skipped": 0,
    "git_commit": "5e17870a6457947826be30aa316c027412ea5492",
    "git_dirty": false,
    "network_requests_to_targets": 0,
    "pandaward_version": "0.2.1",
    "profile": "local-passive",
    "runs": [
      {
        "id": "builtin-inventory-20261028T204903.241Z",
        "adapter": "builtin-inventory",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "15 assets",
        "signals": 3
      },
      {
        "id": "builtin-secrets-20261028T204903.241Z",
        "adapter": "builtin-secrets",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "16 secret formats checked; 1 sensitive file names recorded without reading",
        "signals": 3
      },
      {
        "id": "builtin-code-20261028T204903.242Z",
        "adapter": "builtin-code",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "code heuristics",
        "signals": 12
      },
      {
        "id": "builtin-cicd-20261028T204903.244Z",
        "adapter": "builtin-cicd",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "1 workflows",
        "signals": 5
      },
      {
        "id": "builtin-infra-20261028T204903.244Z",
        "adapter": "builtin-infra",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "dockerfile/compose/k8s/terraform checks",
        "signals": 4
      },
      {
        "id": "builtin-supply-20261028T204903.244Z",
        "adapter": "builtin-supply",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "lockfiles, install scripts, requirement pins, MCP configs",
        "signals": 1
      },
      {
        "id": "builtin-mobile-20261028T204903.245Z",
        "adapter": "builtin-mobile",
        "tool_version": "0.2.1",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "OK",
        "detail": "android manifest, iOS plist and entitlements, mobile storage checks",
        "signals": 3
      },
      {
        "id": "gitleaks-20261028T204903.245Z",
        "adapter": "gitleaks",
        "tool_version": "",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "BLOCKED",
        "detail": "gitleaks is not installed (optional; run `pandaward doctor`)",
        "signals": 0
      },
      {
        "id": "semgrep-20261028T204903.245Z",
        "adapter": "semgrep",
        "tool_version": "",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "BLOCKED",
        "detail": "semgrep is not installed (optional; run `pandaward doctor`)",
        "signals": 0
      },
      {
        "id": "osv-scanner-20261028T204903.245Z",
        "adapter": "osv-scanner",
        "tool_version": "",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "BLOCKED",
        "detail": "osv-scanner is not installed (optional; run `pandaward doctor`)",
        "signals": 0
      },
      {
        "id": "trivy-20261028T204903.245Z",
        "adapter": "trivy",
        "tool_version": "",
        "started_at": "2026-10-28T20:49:03Z",
        "ended_at": "2026-10-28T20:49:03Z",
        "exit_class": "BLOCKED",
        "detail": "trivy is not installed (optional; run `pandaward doctor`)",
        "signals": 0
      }
    ],
    "schema_version": 1
  }
}