{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "discovery-finding-schema",
  "title": "Discovery Finding Schema",
  "description": "Schema for perspective-based issue discovery results",
  "type": "object",
  "required": ["perspective", "discovery_id", "analysis_timestamp", "cli_tool_used", "summary", "findings"],
  "properties": {
    "perspective": {
      "type": "string",
      "enum": ["bug", "ux", "test", "quality", "security", "performance", "maintainability", "best-practices"],
      "description": "Discovery perspective"
    },
    "discovery_id": {
      "type": "string",
      "pattern": "^DSC-\\d{8}-\\d{6}$",
      "description": "Parent discovery session ID"
    },
    "analysis_timestamp": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp of analysis"
    },
    "cli_tool_used": {
      "type": "string",
      "enum": ["gemini", "qwen", "codex"],
      "description": "CLI tool that performed the analysis"
    },
    "model": {
      "type": "string",
      "description": "Specific model version used",
      "examples": ["gemini-2.5-pro", "qwen-max"]
    },
    "analysis_duration_ms": {
      "type": "integer",
      "minimum": 0,
      "description": "Analysis duration in milliseconds"
    },
    "summary": {
      "type": "object",
      "required": ["total_findings"],
      "properties": {
        "total_findings": { "type": "integer", "minimum": 0 },
        "critical": { "type": "integer", "minimum": 0 },
        "high": { "type": "integer", "minimum": 0 },
        "medium": { "type": "integer", "minimum": 0 },
        "low": { "type": "integer", "minimum": 0 },
        "files_analyzed": { "type": "integer", "minimum": 0 }
      },
      "description": "Summary statistics (FLAT structure, NOT nested)"
    },
    "findings": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "title", "perspective", "priority", "category", "description", "file", "line"],
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^dsc-[a-z]+-\\d{3}-[a-f0-9]{8}$",
            "description": "Unique finding ID: dsc-{perspective}-{seq}-{uuid8}",
            "examples": ["dsc-bug-001-a1b2c3d4"]
          },
          "title": {
            "type": "string",
            "minLength": 10,
            "maxLength": 200,
            "description": "Concise finding title"
          },
          "perspective": {
            "type": "string",
            "enum": ["bug", "ux", "test", "quality", "security", "performance", "maintainability", "best-practices"]
          },
          "priority": {
            "type": "string",
            "enum": ["critical", "high", "medium", "low"],
            "description": "Priority level (lowercase only)"
          },
          "category": {
            "type": "string",
            "description": "Perspective-specific category",
            "examples": ["null-check", "edge-case", "missing-test", "complexity", "injection"]
          },
          "description": {
            "type": "string",
            "minLength": 20,
            "description": "Detailed description of the finding"
          },
          "file": {
            "type": "string",
            "description": "File path relative to project root"
          },
          "line": {
            "type": "integer",
            "minimum": 1,
            "description": "Line number of the finding"
          },
          "snippet": {
            "type": "string",
            "description": "Relevant code snippet"
          },
          "suggested_issue": {
            "type": "object",
            "required": ["title", "type", "priority"],
            "properties": {
              "title": {
                "type": "string",
                "description": "Suggested issue title for export"
              },
              "type": {
                "type": "string",
                "enum": ["bug", "feature", "enhancement", "refactor", "test", "docs"],
                "description": "Issue type"
              },
              "priority": {
                "type": "integer",
                "minimum": 1,
                "maximum": 5,
                "description": "Priority 1-5 (1=critical, 5=low)"
              },
              "tags": {
                "type": "array",
                "items": { "type": "string" },
                "description": "Suggested tags for the issue"
              }
            },
            "description": "Pre-filled issue suggestion for export"
          },
          "external_reference": {
            "type": ["object", "null"],
            "properties": {
              "source": { "type": "string" },
              "url": { "type": "string", "format": "uri" },
              "relevance": { "type": "string" }
            },
            "description": "External reference from Exa research (if applicable)"
          },
          "confidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Confidence score 0.0-1.0"
          },
          "impact": {
            "type": "string",
            "description": "Description of potential impact"
          },
          "recommendation": {
            "type": "string",
            "description": "Specific recommendation to address the finding"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true,
            "description": "Additional metadata (CWE ID, OWASP category, etc.)"
          }
        }
      },
      "description": "Array of discovered findings"
    },
    "cross_references": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "finding_id": { "type": "string" },
          "related_perspectives": {
            "type": "array",
            "items": { "type": "string" }
          },
          "reason": { "type": "string" }
        }
      },
      "description": "Cross-references to findings in other perspectives"
    }
  },
  "examples": [
    {
      "perspective": "bug",
      "discovery_id": "DSC-20250128-143022",
      "analysis_timestamp": "2025-01-28T14:35:00Z",
      "cli_tool_used": "gemini",
      "model": "gemini-2.5-pro",
      "analysis_duration_ms": 45000,
      "summary": {
        "total_findings": 8,
        "critical": 1,
        "high": 2,
        "medium": 3,
        "low": 2,
        "files_analyzed": 5
      },
      "findings": [
        {
          "id": "dsc-bug-001-a1b2c3d4",
          "title": "Missing null check in user validation",
          "perspective": "bug",
          "priority": "high",
          "category": "null-check",
          "description": "User object is accessed without null check after database query, which may fail if user doesn't exist",
          "file": "src/auth/validator.ts",
          "line": 45,
          "snippet": "const user = await db.findUser(id);\nreturn user.email;  // user may be null",
          "suggested_issue": {
            "title": "Add null check in user validation",
            "type": "bug",
            "priority": 2,
            "tags": ["bug", "auth"]
          },
          "external_reference": null,
          "confidence": 0.85,
          "impact": "Runtime error when user not found",
          "recommendation": "Add null check: if (!user) throw new NotFoundError('User not found');"
        }
      ],
      "cross_references": []
    }
  ]
}
