{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://www.motherhacker.me/kgcs/schema/request-schema.json",
  "title": "KGCS Agent Request Envelope",
  "description": "Request envelope sent by the orchestrator to subagents, or by external callers to the orchestrator. Intent-specific payload requirements are enforced via allOf conditionals.",
  "type": "object",
  "required": ["version", "correlation_id", "agent", "intent", "payload"],
  "additionalProperties": false,
  "properties": {
    "version": {
      "type": "string",
      "enum": ["1.0"],
      "description": "Contract version. Unversioned requests are rejected."
    },
    "correlation_id": {
      "type": "string",
      "format": "uuid",
      "description": "UUID generated by the caller and propagated end-to-end."
    },
    "agent": {
      "type": "string",
      "enum": ["master", "systems", "offensive", "defensive"],
      "description": "Target agent. 'master' for the orchestrator entry point."
    },
    "intent": {
      "type": "string",
      "enum": ["vuln_lookup", "attack_path", "coverage_map", "mixed"],
      "description": "Query intent. Determines which agent(s) are invoked and which payload fields are required."
    },
    "payload": {
      "type": "object",
      "description": "Intent-specific parameters. Required fields vary by intent — see allOf conditionals below."
    },
    "constraints": {
      "type": "object",
      "additionalProperties": false,
      "description": "Optional query execution constraints.",
      "properties": {
        "max_hops": {
          "type": "integer",
          "minimum": 1,
          "maximum": 10,
          "default": 4,
          "description": "Maximum causal chain hops to traverse. Capped at 6 (full chain depth)."
        },
        "allow_extensions": {
          "type": "boolean",
          "default": false,
          "description": "Whether to include Risk/Incident/ThreatActor extension nodes in traversal."
        }
      }
    }
  },
  "allOf": [
    {
      "description": "vuln_lookup: payload must contain cpe OR cveId (asset-to-vulnerability query).",
      "if": {
        "properties": { "intent": { "const": "vuln_lookup" } },
        "required": ["intent"]
      },
      "then": {
        "properties": {
          "payload": {
            "anyOf": [
              {
                "required": ["cpe"],
                "properties": {
                  "cpe": {
                    "type": "string",
                    "description": "CPE URI or matchCriteriaId to look up vulnerabilities for.",
                    "examples": ["cpe:2.3:a:apache:log4j:2.14.1:*:*:*:*:*:*:*", "8a5c4e5b-3d6f-4a7e-9b8c-2d3e4f5a6b7c"]
                  }
                }
              },
              {
                "required": ["cveId"],
                "properties": {
                  "cveId": {
                    "type": "string",
                    "pattern": "^CVE-\\d{4}-\\d+$",
                    "description": "Exact CVE identifier.",
                    "examples": ["CVE-2021-44228"]
                  }
                }
              }
            ]
          }
        }
      }
    },
    {
      "description": "attack_path: payload must contain cveId OR cweId (weakness-to-technique traversal).",
      "if": {
        "properties": { "intent": { "const": "attack_path" } },
        "required": ["intent"]
      },
      "then": {
        "properties": {
          "payload": {
            "anyOf": [
              {
                "required": ["cveId"],
                "properties": {
                  "cveId": {
                    "type": "string",
                    "pattern": "^CVE-\\d{4}-\\d+$",
                    "description": "CVE identifier. Orchestrator resolves to CWE before forwarding to Offensive Agent."
                  }
                }
              },
              {
                "required": ["cweId"],
                "properties": {
                  "cweId": {
                    "type": "string",
                    "pattern": "^CWE-\\d+$",
                    "description": "Direct weakness ID for attack path traversal.",
                    "examples": ["CWE-917", "CWE-79"]
                  }
                }
              }
            ]
          }
        }
      }
    },
    {
      "description": "coverage_map: payload must contain attackId (Technique or SubTechnique identifier).",
      "if": {
        "properties": { "intent": { "const": "coverage_map" } },
        "required": ["intent"]
      },
      "then": {
        "properties": {
          "payload": {
            "required": ["attackId"],
            "properties": {
              "attackId": {
                "type": "string",
                "pattern": "^T\\d{4}(\\.\\d{3})?$",
                "description": "ATT&CK technique or subtechnique ID.",
                "examples": ["T1059", "T1059.001"]
              }
            }
          }
        }
      }
    },
    {
      "description": "mixed: payload must contain cpe OR cveId. Orchestrator composes Systems → Offensive → Defensive sequentially.",
      "if": {
        "properties": { "intent": { "const": "mixed" } },
        "required": ["intent"]
      },
      "then": {
        "properties": {
          "payload": {
            "anyOf": [
              {
                "required": ["cpe"],
                "properties": {
                  "cpe": {
                    "type": "string",
                    "description": "CPE URI or matchCriteriaId. Orchestrator resolves to CVE, then CWE, then techniques, then coverage."
                  }
                }
              },
              {
                "required": ["cveId"],
                "properties": {
                  "cveId": {
                    "type": "string",
                    "pattern": "^CVE-\\d{4}-\\d+$",
                    "description": "CVE identifier. Orchestrator resolves chain without requiring CPE."
                  }
                }
              }
            ]
          }
        }
      }
    }
  ],
  "examples": [
    {
      "version": "1.0",
      "correlation_id": "550e8400-e29b-41d4-a716-446655440000",
      "agent": "systems",
      "intent": "vuln_lookup",
      "payload": { "cveId": "CVE-2021-44228" },
      "constraints": { "max_hops": 4, "allow_extensions": false }
    },
    {
      "version": "1.0",
      "correlation_id": "550e8400-e29b-41d4-a716-446655440001",
      "agent": "offensive",
      "intent": "attack_path",
      "payload": { "cweId": "CWE-917" },
      "constraints": { "max_hops": 6 }
    },
    {
      "version": "1.0",
      "correlation_id": "550e8400-e29b-41d4-a716-446655440002",
      "agent": "defensive",
      "intent": "coverage_map",
      "payload": { "attackId": "T1190" }
    },
    {
      "version": "1.0",
      "correlation_id": "550e8400-e29b-41d4-a716-446655440003",
      "agent": "master",
      "intent": "mixed",
      "payload": { "cveId": "CVE-2021-44228" },
      "constraints": { "max_hops": 6, "allow_extensions": false }
    }
  ]
}
