{
  "id": "data.report.ingest.v1",
  "name": "Report Data Ingestion Policy",
  "description": "Pre-action governance for data being ingested by an AI agent for reporting purposes (e.g., ESG, financial disclosures). Enforces rules on data source credibility and freshness.",
  "version": "1.0.0",
  "status": "active",
  "requires_capabilities": ["data.report.ingest"],
  "min_assurance": "L2",
  "limits_required": [
    "approved_sources",
    "max_data_age_seconds",
    "max_data_size_mb",
    "max_ingest_frequency_per_hour",
    "data_quality_threshold",
    "required_validation_checks"
  ],
  "required_fields": ["report_type", "data_source_id", "data_timestamp"],
  "optional_fields": [
    "metric_type",
    "data_size_mb",
    "validation_checks",
    "data_quality_score",
    "ingest_reason",
    "idempotency_key"
  ],
  "enforcement": {
    "source_approved": true,
    "data_freshness": true,
    "data_size_limit": true,
    "ingest_frequency_limit": true,
    "data_quality_enforced": true,
    "validation_required": true,
    "idempotency_required": true
  },
  "mcp": {
    "require_allowlisted_if_present": true
  },
  "advice": [
    "Cache /verify with ETag; 60s TTL",
    "Subscribe to status webhooks for instant suspend",
    "Log all data ingestion attempts for Verifiable Attestation",
    "Implement data quality scoring before ingestion",
    "Use data lineage tracking for audit compliance",
    "Implement progressive data validation checks",
    "Monitor for data anomalies and unusual patterns",
    "Use data encryption for sensitive report data",
    "Implement data retention policies based on report type",
    "Maintain data source reputation scoring",
    "Use idempotency keys to prevent duplicate ingestion",
    "Implement data freshness monitoring and alerts"
  ],
  "cache": {
    "default_ttl_seconds": 300,
    "suspend_invalidate_seconds": 60
  },
  "required_context": {
    "$schema": "http://json-schema.org/draft-07/schema#",
    "type": "object",
    "required": ["report_type", "data_source_id", "data_timestamp"],
    "properties": {
      "report_type": {
        "type": "string",
        "description": "The type of report being generated (e.g., 'ESG', 'QuarterlyFinancials')."
      },
      "data_source_id": {
        "type": "string",
        "description": "A unique identifier for the source of the data being ingested (e.g., 'api.climate-data.com', 'internal-hr-db')."
      },
      "data_timestamp": {
        "type": "string",
        "format": "date-time",
        "description": "The ISO 8601 timestamp of when the data was generated."
      },
      "metric_type": {
        "type": "string",
        "description": "The specific metric this data point relates to (e.g., 'carbon_emissions', 'employee_diversity')."
      },
      "mcp_servers": {
        "type": "array",
        "items": { "type": "string" },
        "description": "MCP servers being used in this request (e.g., [\"https://mcp.climate-data.com\"])"
      },
      "mcp_tools": {
        "type": "array",
        "items": { "type": "string" },
        "description": "MCP tools being used in this request (e.g., [\"climate_data.reports.ingest\"])"
      },
      "mcp_server": {
        "type": "string",
        "description": "Single MCP server being used (backward compatibility - use mcp_servers array for multiple)"
      },
      "mcp_tool": {
        "type": "string",
        "description": "Single MCP tool being used (backward compatibility - use mcp_tools array for multiple)"
      },
      "mcp_session": {
        "type": "string",
        "description": "MCP session identifier for audit trail (optional)"
      }
    }
  },
  "evaluation_rules": [
    {
      "name": "passport_status_active",
      "condition": "passport.status == 'active'",
      "deny_code": "oap.passport_suspended"
    },
    {
      "name": "source_is_approved",
      "condition": "context.data_source_id in passport.limits.data.report.ingest[context.report_type].approved_sources",
      "deny_code": "oap.source_unapproved"
    },
    {
      "name": "data_is_fresh",
      "condition": "(now() - to_timestamp(context.data_timestamp)) <= passport.limits.data.report.ingest[context.report_type].max_data_age_seconds",
      "deny_code": "oap.data_stale",
      "description": "Data must not be older than maximum allowed age for the report type."
    },
    {
      "name": "assurance_minimum",
      "condition": "passport.assurance_level >= policy.min_assurance",
      "deny_code": "oap.assurance_insufficient",
      "description": "Assurance level must meet minimum requirement for data ingestion."
    },
    {
      "name": "data_size_limit_check",
      "condition": "not context.data_size_mb or context.data_size_mb <= passport.limits.data.report.ingest[context.report_type].max_data_size_mb",
      "deny_code": "oap.data_size_exceeded",
      "description": "Data size must not exceed maximum allowed for the report type."
    },
    {
      "name": "ingest_frequency_check",
      "condition": "ingest_count_per_hour[context.data_source_id] < passport.limits.data.report.ingest[context.report_type].max_ingest_frequency_per_hour",
      "deny_code": "oap.ingest_frequency_exceeded",
      "description": "Data source ingestion frequency must not exceed hourly limit."
    },
    {
      "name": "data_quality_check",
      "condition": "not context.data_quality_score or context.data_quality_score >= passport.limits.data.report.ingest[context.report_type].data_quality_threshold",
      "deny_code": "oap.data_quality_insufficient",
      "description": "Data quality score must meet minimum threshold."
    },
    {
      "name": "validation_checks_required",
      "condition": "context.validation_checks and all(check in passport.limits.data.report.ingest[context.report_type].required_validation_checks for check in context.validation_checks)",
      "deny_code": "oap.validation_checks_missing",
      "description": "All required validation checks must be performed."
    },
    {
      "name": "idempotency_check",
      "condition": "context.idempotency_key not in recent_keys",
      "deny_code": "oap.idempotency_conflict",
      "description": "Idempotency key must be unique to prevent duplicate ingestion."
    },
    {
      "name": "report_type_allowed",
      "condition": "context.report_type in passport.limits.data.report.ingest.allowed_report_types",
      "deny_code": "oap.report_type_forbidden",
      "description": "Report type must be in the allowed list."
    },
    {
      "name": "data_source_reputation_check",
      "condition": "data_source_reputation[context.data_source_id] >= passport.limits.data.report.ingest.min_source_reputation_score",
      "deny_code": "oap.source_reputation_insufficient",
      "description": "Data source must meet minimum reputation score."
    },
    {
      "name": "metric_type_validation",
      "condition": "not context.metric_type or context.metric_type in passport.limits.data.report.ingest[context.report_type].allowed_metric_types",
      "deny_code": "oap.metric_type_forbidden",
      "description": "Metric type must be allowed for the report type."
    }
  ]
}
