{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://preclari.com/pif/v0.1/preflight-assertion.schema.json",
  "title": "PIF PreflightAssertion",
  "description": "The output of a preflight assessment against a WorkflowDescription. The audit-defensible artifact. PIF (Preflight Interchange Format) v0.1.",
  "type": "object",
  "required": [
    "pif_version",
    "assertion_id",
    "workflow_ref",
    "produced_by",
    "produced_at",
    "risk_classification",
    "applicable_requirements",
    "missing_controls",
    "assumptions_made",
    "verification_steps",
    "status"
  ],
  "properties": {
    "pif_version": {
      "type": "string",
      "const": "0.1"
    },
    "assertion_id": {
      "type": "string",
      "pattern": "^[a-zA-Z0-9_:.-]{4,128}$",
      "description": "Stable identifier for this assertion."
    },
    "workflow_ref": {
      "type": "string",
      "description": "The workflow_id of the WorkflowDescription this assertion was produced against."
    },
    "workflow_snapshot": {
      "$ref": "workflow-description.schema.json",
      "description": "Optional embedded snapshot of the WorkflowDescription at the time of assessment. Recommended for archival; ensures the assertion remains interpretable if the source workflow changes."
    },
    "produced_by": {
      "type": "object",
      "required": ["tool", "version"],
      "properties": {
        "tool": {
          "type": "string",
          "description": "Name of the tool that produced this assertion (e.g., 'preclari')."
        },
        "version": {
          "type": "string",
          "description": "Version of the producing tool."
        },
        "methodology": {
          "type": "string",
          "description": "Version of the methodology used (e.g., 'preclari-method-v1.0'). Methodology versioning enables comparison of assertions over time."
        },
        "tier": {
          "type": "string",
          "enum": ["requested_access", "builder", "practice", "team", "private"],
          "description": "Service tier under which this assertion was produced. Informational; affects entitlements rather than schema."
        },
        "workspace_id": {
          "type": "string",
          "description": "Identifier of the workspace within which this assertion was produced."
        },
        "provider": {
          "type": "string",
          "description": "The LLM provider that served the primary reasoning step (e.g., 'gemini', 'anthropic'). Provider-neutral by design; producers SHOULD populate this so PIF documents are honest about which provider produced the assertion. Per-step provider/model routing lives in model_assignments."
        },
        "model_used": {
          "type": "string",
          "description": "The model identifier that served the primary reasoning step (e.g., 'gemini-2.5-flash', 'claude-haiku-4-5'). Producers SHOULD echo back the model string actually used by the provider rather than a hardcoded default — replayability requires the real model identifier."
        },
        "model_assignments": {
          "type": "object",
          "description": "Which model was used for which reasoning step. Keys are step names; values are model identifiers.",
          "additionalProperties": {
            "type": "string"
          }
        },
        "entitlements": {
          "type": "object",
          "description": "What the producing instance was permitted to use. Audit-relevant: 'could the system have considered X?'",
          "properties": {
            "jurisdictions": {
              "type": "array",
              "items": { "type": "string" }
            },
            "gxp_domains": {
              "type": "array",
              "items": { "type": "string" }
            },
            "premium_features": {
              "type": "array",
              "items": { "type": "string" }
            }
          }
        }
      }
    },
    "produced_at": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 timestamp of when the assertion was produced."
    },
    "corpus_snapshot": {
      "type": "object",
      "description": "Identifier of the corpus state at the time of assertion. Required for audit-defensible outputs.",
      "properties": {
        "snapshot_id": {
          "type": "string"
        },
        "snapshot_hash": {
          "type": "string",
          "pattern": "^sha256:[a-f0-9]{64}$"
        },
        "snapshot_date": {
          "type": "string",
          "format": "date-time"
        },
        "source_count": {
          "type": "integer",
          "minimum": 0
        }
      }
    },
    "risk_classification": {
      "type": "object",
      "required": ["level", "rationale"],
      "properties": {
        "level": {
          "type": "string",
          "enum": ["low", "medium", "high", "critical"]
        },
        "rationale": {
          "type": "string",
          "minLength": 20,
          "description": "Why this risk level was assigned. Should reference workflow attributes."
        },
        "drivers": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Specific workflow attributes that drove the classification (e.g., 'output_destination=regulated_decision', 'reversibility=irreversible')."
        }
      }
    },
    "gxp_domains_identified": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "GMP", "GDP", "GCP", "GLP", "GVP",
          "CSV", "data_integrity", "quality_systems",
          "regulatory_affairs", "pharmacovigilance", "labeling"
        ]
      },
      "uniqueItems": true,
      "description": "GxP domains identified as relevant by the preflight, which may differ from gxp_domains_self_declared in the WorkflowDescription."
    },
    "applicable_requirements": {
      "type": "array",
      "items": { "$ref": "#/$defs/RequirementProjection" },
      "description": "Requirements identified as applicable to this workflow, with applicability basis and source provenance."
    },
    "missing_controls": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["control", "rationale"],
        "properties": {
          "control": {
            "type": "string",
            "description": "Name of the control (e.g., 'audit_trail', 'human_approval_gate', 'validated_source_retrieval')."
          },
          "rationale": {
            "type": "string"
          },
          "criticality": {
            "type": "string",
            "enum": ["required", "recommended", "advisable"]
          },
          "related_requirements": {
            "type": "array",
            "items": { "type": "string" },
            "description": "References to requirement IDs in applicable_requirements that this control addresses."
          }
        }
      }
    },
    "assumptions_made": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["assumption", "impact_if_wrong"],
        "properties": {
          "assumption": { "type": "string" },
          "impact_if_wrong": { "type": "string" },
          "basis": {
            "type": "string",
            "description": "Why the assumption was made (e.g., 'field not provided in WorkflowDescription', 'inferred from intent text')."
          }
        }
      },
      "description": "Inferences the preflight made when WorkflowDescription fields were missing or ambiguous. CRITICAL for audit: makes the system's reasoning legible."
    },
    "clarifying_questions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["question", "would_change"],
        "properties": {
          "question": { "type": "string" },
          "would_change": {
            "type": "string",
            "description": "What aspect of the assertion would change if this question were answered."
          }
        }
      },
      "description": "Questions that, if answered, would materially change the output."
    },
    "out_of_scope": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["topic", "reason"],
        "properties": {
          "topic": { "type": "string" },
          "reason": { "type": "string" }
        }
      },
      "description": "Topics, jurisdictions, or considerations that were explicitly NOT addressed, with reason."
    },
    "superseded_or_excluded": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["source", "reason"],
        "properties": {
          "source": { "$ref": "#/$defs/SourceReference" },
          "reason": { "type": "string" }
        }
      },
      "description": "Sources considered and deliberately ruled out (e.g., superseded guidance), with reason. Honesty by architecture."
    },
    "cross_jurisdiction_conflicts": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["topic", "jurisdictions_involved", "nature_of_conflict"],
        "properties": {
          "topic": { "type": "string" },
          "jurisdictions_involved": {
            "type": "array",
            "items": { "type": "string" }
          },
          "nature_of_conflict": {
            "type": "string",
            "enum": ["divergent_requirements", "differing_thresholds", "scope_disagreement", "procedural_difference"]
          },
          "summary": { "type": "string" },
          "related_requirements": {
            "type": "array",
            "items": { "type": "string" }
          }
        }
      }
    },
    "verification_steps": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["step", "type"],
        "properties": {
          "step": {
            "type": "string",
            "description": "A specific action a human auditor can take to independently verify this assertion."
          },
          "type": {
            "type": "string",
            "enum": ["source_check", "requirement_lookup", "expert_review", "internal_policy_check", "external_validation"]
          },
          "applies_to": {
            "type": "string",
            "description": "Reference to which part of the assertion this step verifies (e.g., 'risk_classification', 'applicable_requirements[3]')."
          }
        }
      },
      "description": "How a human can independently audit this assertion. Required for audit-defensibility."
    },
    "reasoning_trace": {
      "type": "object",
      "description": "Optional structured reasoning trace. Required for premium outputs.",
      "properties": {
        "decision_points": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "decision": { "type": "string" },
              "alternatives_considered": {
                "type": "array",
                "items": { "type": "string" }
              },
              "basis_for_choice": { "type": "string" },
              "confidence": {
                "type": "string",
                "enum": ["high", "medium", "low"]
              }
            }
          }
        },
        "uncertainty_sources": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "source": { "type": "string" },
              "type": {
                "type": "string",
                "enum": ["model_uncertainty", "corpus_gap", "ambiguous_input", "contested_interpretation"]
              }
            }
          }
        }
      }
    },
    "recommendation": {
      "type": "string",
      "description": "Overall recommendation for the workflow. Should never include phrasing that implies regulatory authority (e.g., 'you are compliant'). Use action-oriented language."
    },
    "reviewer_actions": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["reviewer", "action", "timestamp"],
        "properties": {
          "reviewer": { "type": "string" },
          "action": {
            "type": "string",
            "enum": ["approved", "overridden", "flagged", "annotated", "rejected"]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          },
          "applies_to": { "type": "string" },
          "note": { "type": "string" },
          "override_value": {
            "description": "If action is 'overridden', the value the reviewer is asserting instead."
          }
        }
      }
    },
    "status": {
      "type": "string",
      "enum": ["draft", "in_review", "approved", "contested", "superseded"]
    },
    "supersedes": {
      "type": "string",
      "description": "If this assertion supersedes a previous one, the previous assertion_id."
    },
    "superseded_by": {
      "type": "string",
      "description": "If this assertion has been superseded, the new assertion_id."
    },
    "signature": {
      "type": "object",
      "description": "Optional cryptographic signature. Required by RegCheck's paid tiers; optional in the PIF spec. Producers SHOULD sign over the canonicalized form of the document with the signature field removed.",
      "properties": {
        "algorithm": {
          "type": "string",
          "enum": ["Ed25519", "RSA-PSS-SHA256", "ECDSA-P256-SHA256"]
        },
        "public_key_id": { "type": "string" },
        "signature_value": {
          "type": "string",
          "description": "Base64-encoded signature."
        },
        "canonicalization": {
          "type": "string",
          "enum": ["JCS-RFC8785"],
          "description": "Canonicalization scheme used before signing."
        }
      }
    },
    "notice": {
      "type": "string",
      "description": "Free-text notice. May be used by implementations to indicate tier-specific limitations (e.g., 'Produced under free tier; not signed')."
    },
    "extensions": {
      "type": "object",
      "description": "Implementation-specific extensions."
    }
  },
  "additionalProperties": false,
  "$defs": {
    "SourceReference": {
      "type": "object",
      "required": ["url"],
      "properties": {
        "url": {
          "type": "string",
          "format": "uri"
        },
        "canonical_document_id": {
          "type": "string",
          "description": "Stable identifier for the document independent of URL (e.g., 'EMA/CHMP/123/2024')."
        },
        "title": { "type": "string" },
        "issuing_authority": { "type": "string" },
        "jurisdiction": { "type": "string" },
        "document_type": {
          "type": "string",
          "enum": ["guidance", "regulation", "directive", "guideline", "annex", "qa", "reflection_paper", "inspection_guide", "other"]
        },
        "section_anchor": {
          "type": "string",
          "description": "Specific section, paragraph, or clause within the document (e.g., 'Section 4.2', 'Annex 11 §5')."
        },
        "effective_date": {
          "type": "string",
          "format": "date"
        },
        "superseded_date": {
          "type": "string",
          "format": "date"
        },
        "retrieved_at": {
          "type": "string",
          "format": "date-time"
        },
        "content_hash": {
          "type": "string",
          "pattern": "^sha256:[a-f0-9]{64}$",
          "description": "Hash of the retrieved content for verification."
        },
        "excerpt": {
          "type": "string",
          "maxLength": 1000,
          "description": "Exact excerpt from the source. Short. Used for verification, not reproduction."
        }
      }
    },
    "RequirementProjection": {
      "type": "object",
      "required": ["requirement_id", "requirement_text", "source", "applicability_basis", "confidence"],
      "properties": {
        "requirement_id": {
          "type": "string",
          "description": "Stable ID for this requirement within the assertion."
        },
        "requirement_text": {
          "type": "string",
          "description": "The requirement, summarized or quoted briefly. Producers must not reproduce substantial portions of copyrighted material."
        },
        "source": { "$ref": "#/$defs/SourceReference" },
        "applicability_basis": {
          "type": "string",
          "minLength": 20,
          "description": "The reasoning chain from workflow attributes to this requirement's applicability. Not optional."
        },
        "confidence": {
          "type": "string",
          "enum": ["high", "medium", "low", "contested"]
        },
        "jurisdictional_scope": {
          "type": "array",
          "items": { "type": "string" }
        },
        "interpretation_notes": {
          "type": "string"
        },
        "related_requirements": {
          "type": "array",
          "items": { "type": "string" }
        }
      }
    }
  }
}
