feat: add security sink detection patterns for JavaScript/TypeScript

- Introduced `sink-detect.js` with various security sink detection patterns categorized by type (e.g., command injection, SQL injection, file operations).
- Implemented functions to build a lookup map for fast sink detection and to match sink calls against known patterns.
- Added `package-lock.json` for dependency management.
This commit is contained in:
StellaOps Bot
2025-12-22 23:21:21 +02:00
parent 3ba7157b00
commit 5146204f1b
529 changed files with 73579 additions and 5985 deletions

View File

@@ -0,0 +1,234 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/calibration-manifest/1.0.0",
"title": "Calibration Manifest Schema",
"description": "Schema for trust vector calibration manifests that track tuning history",
"type": "object",
"required": [
"manifest_id",
"tenant",
"epoch",
"started_at",
"completed_at",
"calibrations"
],
"properties": {
"manifest_id": {
"type": "string",
"description": "Unique identifier for the calibration manifest"
},
"tenant": {
"type": "string",
"minLength": 1,
"description": "Tenant identifier for multi-tenancy"
},
"epoch": {
"type": "integer",
"minimum": 1,
"description": "Calibration epoch number"
},
"started_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp when calibration started"
},
"completed_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp when calibration completed"
},
"calibrations": {
"type": "array",
"items": {
"$ref": "#/$defs/SourceCalibration"
},
"description": "Per-source calibration results"
},
"config": {
"$ref": "#/$defs/CalibrationConfig"
},
"metrics": {
"$ref": "#/$defs/CalibrationMetrics"
}
},
"additionalProperties": false,
"$defs": {
"SourceCalibration": {
"type": "object",
"description": "Calibration result for a single VEX source",
"required": [
"source_id",
"previous_vector",
"new_vector",
"adjustments",
"sample_count"
],
"properties": {
"source_id": {
"type": "string",
"description": "Identifier of the VEX source"
},
"previous_vector": {
"$ref": "trust-vector.schema.json",
"description": "Trust vector before calibration"
},
"new_vector": {
"$ref": "trust-vector.schema.json",
"description": "Trust vector after calibration"
},
"adjustments": {
"$ref": "#/$defs/VectorAdjustments"
},
"sample_count": {
"type": "integer",
"minimum": 0,
"description": "Number of post-mortem samples used"
},
"accuracy_before": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Accuracy before calibration"
},
"accuracy_after": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Accuracy after calibration"
}
},
"additionalProperties": false
},
"VectorAdjustments": {
"type": "object",
"description": "Adjustments applied to trust vector components",
"properties": {
"provenance_delta": {
"type": "number",
"description": "Change in Provenance score"
},
"coverage_delta": {
"type": "number",
"description": "Change in Coverage score"
},
"replayability_delta": {
"type": "number",
"description": "Change in Replayability score"
}
},
"additionalProperties": false
},
"CalibrationConfig": {
"type": "object",
"description": "Configuration used for this calibration run",
"properties": {
"learning_rate": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.02,
"description": "Maximum adjustment per epoch"
},
"momentum": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.1,
"description": "Momentum for smoothing adjustments"
},
"min_samples": {
"type": "integer",
"minimum": 1,
"default": 10,
"description": "Minimum samples required for calibration"
},
"accuracy_threshold": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.7,
"description": "Target accuracy threshold"
}
},
"additionalProperties": false
},
"CalibrationMetrics": {
"type": "object",
"description": "Aggregate metrics for the calibration epoch",
"properties": {
"total_samples": {
"type": "integer",
"minimum": 0,
"description": "Total post-mortem samples processed"
},
"sources_calibrated": {
"type": "integer",
"minimum": 0,
"description": "Number of sources calibrated"
},
"sources_skipped": {
"type": "integer",
"minimum": 0,
"description": "Number of sources skipped (insufficient samples)"
},
"average_accuracy_improvement": {
"type": "number",
"description": "Average accuracy improvement across sources"
},
"max_drift": {
"type": "number",
"minimum": 0,
"description": "Maximum calibration drift detected"
}
},
"additionalProperties": false
},
"PostMortemOutcome": {
"type": "object",
"description": "Post-mortem truth for calibration comparison",
"required": [
"vulnerability_id",
"asset_digest",
"predicted_status",
"actual_status",
"source_id",
"recorded_at"
],
"properties": {
"vulnerability_id": {
"type": "string",
"description": "CVE or vulnerability identifier"
},
"asset_digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "Asset digest"
},
"predicted_status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "Status predicted by trust lattice"
},
"actual_status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed"],
"description": "Confirmed actual status"
},
"source_id": {
"type": "string",
"description": "Source that made the prediction"
},
"recorded_at": {
"type": "string",
"format": "date-time",
"description": "When the post-mortem was recorded"
},
"evidence_ref": {
"type": "string",
"description": "Reference to evidence supporting the truth"
}
},
"additionalProperties": false
}
}
}

View File

@@ -0,0 +1,231 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/claim-score/1.0.0",
"title": "Claim Score Schema",
"description": "Schema for VEX claim scoring in the trust lattice",
"type": "object",
"required": [
"source_id",
"status",
"base_trust",
"strength_multiplier",
"freshness_multiplier",
"claim_score"
],
"properties": {
"source_id": {
"type": "string",
"description": "Identifier of the VEX source"
},
"status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "VEX status asserted by this claim"
},
"trust_vector": {
"$ref": "trust-vector.schema.json",
"description": "Trust vector for the source"
},
"base_trust": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "BaseTrust(S) = wP*P + wC*C + wR*R"
},
"strength": {
"type": "string",
"enum": [
"exploitability_with_reachability",
"config_with_evidence",
"vendor_blanket",
"under_investigation"
],
"description": "Claim strength category"
},
"strength_multiplier": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Strength multiplier (M) based on evidence quality"
},
"issued_at": {
"type": "string",
"format": "date-time",
"description": "When the claim was issued"
},
"freshness_multiplier": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Freshness decay multiplier (F)"
},
"claim_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Final score: BaseTrust * M * F"
},
"adjusted_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Score after conflict penalty (if applicable)"
},
"conflict_penalty_applied": {
"type": "boolean",
"default": false,
"description": "Whether a conflict penalty was applied"
},
"scope_specificity": {
"type": "integer",
"minimum": 1,
"maximum": 5,
"description": "Scope specificity level (1=exact digest, 5=platform)"
},
"reason": {
"type": "string",
"description": "Human-readable reason for the claim"
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string"
},
"description": "References to supporting evidence"
}
},
"additionalProperties": false,
"$defs": {
"ScoredClaimSet": {
"type": "object",
"description": "A set of scored claims for a single (asset, vulnerability) pair",
"required": [
"asset_digest",
"vulnerability_id",
"claims"
],
"properties": {
"asset_digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 digest of the asset"
},
"vulnerability_id": {
"type": "string",
"description": "Vulnerability identifier"
},
"claims": {
"type": "array",
"items": {
"$ref": "#"
},
"description": "Scored claims for this asset/vulnerability"
},
"has_conflict": {
"type": "boolean",
"description": "Whether conflicting claims exist"
},
"winner": {
"$ref": "#",
"description": "The winning claim"
},
"evaluated_at": {
"type": "string",
"format": "date-time",
"description": "When the scoring was performed"
}
},
"additionalProperties": false
},
"MergeResult": {
"type": "object",
"description": "Result of merging multiple claims into a verdict",
"required": [
"status",
"confidence",
"policy_hash",
"lattice_version"
],
"properties": {
"status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "Merged verdict status"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Confidence in the verdict"
},
"explanations": {
"type": "array",
"items": {
"$ref": "#"
},
"description": "All claims considered"
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Aggregated evidence references"
},
"policy_hash": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "Hash of the policy file"
},
"lattice_version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Trust lattice version"
},
"gates_passed": {
"type": "array",
"items": {
"type": "string"
},
"description": "Policy gates that passed"
},
"gates_failed": {
"type": "array",
"items": {
"type": "string"
},
"description": "Policy gates that failed"
}
},
"additionalProperties": false
},
"ConflictResolution": {
"type": "object",
"description": "Details of how a conflict was resolved",
"properties": {
"conflict_detected": {
"type": "boolean",
"description": "Whether a conflict was detected"
},
"conflicting_statuses": {
"type": "array",
"items": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"]
},
"description": "Distinct statuses in conflict"
},
"penalty_applied": {
"type": "number",
"default": 0.25,
"description": "Penalty applied to weaker claims"
},
"resolution_reason": {
"type": "string",
"description": "Explanation of resolution method"
}
},
"additionalProperties": false
}
}
}

View File

@@ -0,0 +1,297 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/finding-explainability/v2.json",
"title": "Finding Explainability Predicate Schema",
"description": "Schema for finding-explainability/v2 predicate type - vulnerability finding with assumptions, falsifiability criteria, and evidence-based confidence",
"type": "object",
"required": [
"findingId",
"vulnerabilityId",
"packageName",
"packageVersion",
"generatedAt",
"engineVersion"
],
"properties": {
"findingId": {
"type": "string",
"pattern": "^[a-zA-Z0-9-]+$",
"description": "Unique identifier for this finding"
},
"vulnerabilityId": {
"type": "string",
"pattern": "^(CVE-[0-9]{4}-[0-9]+|GHSA-.+|OSV-.+|[A-Z]+-[0-9]+)$",
"description": "The vulnerability ID (CVE, GHSA, OSV, etc.)"
},
"packageName": {
"type": "string",
"minLength": 1,
"description": "Name of the affected package"
},
"packageVersion": {
"type": "string",
"minLength": 1,
"description": "Version of the affected package"
},
"severity": {
"type": "string",
"enum": ["CRITICAL", "HIGH", "MEDIUM", "LOW", "UNKNOWN"],
"description": "Severity level of the vulnerability"
},
"fixedVersion": {
"type": ["string", "null"],
"description": "Version that fixes the vulnerability, if known"
},
"generatedAt": {
"type": "string",
"format": "date-time",
"description": "ISO-8601 timestamp when this report was generated"
},
"engineVersion": {
"type": "string",
"description": "Version of the explainability engine"
},
"explanation": {
"type": "string",
"description": "Human-readable explanation of the finding"
},
"detailedNarrative": {
"type": "string",
"description": "Detailed narrative for auditor review"
},
"assumptions": {
"$ref": "#/$defs/AssumptionSet"
},
"falsifiability": {
"$ref": "#/$defs/FalsifiabilityCriteria"
},
"confidenceScore": {
"$ref": "#/$defs/EvidenceDensityScore"
},
"recommendedActions": {
"type": "array",
"items": {
"$ref": "#/$defs/RecommendedAction"
},
"description": "List of recommended remediation actions"
}
},
"additionalProperties": false,
"$defs": {
"AssumptionSet": {
"type": "object",
"description": "Collection of assumptions made during analysis",
"required": ["id", "createdAt", "assumptions"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this assumption set"
},
"contextId": {
"type": ["string", "null"],
"description": "ID of the finding this assumption set belongs to"
},
"createdAt": {
"type": "string",
"format": "date-time",
"description": "When this assumption set was created"
},
"assumptions": {
"type": "array",
"items": {
"$ref": "#/$defs/Assumption"
},
"description": "List of assumptions"
}
},
"additionalProperties": false
},
"Assumption": {
"type": "object",
"description": "A single assumption made during vulnerability analysis",
"required": ["category", "key", "assumedValue", "source", "confidence"],
"properties": {
"category": {
"type": "string",
"enum": [
"CompilerFlag",
"RuntimeConfig",
"FeatureGate",
"LoaderBehavior",
"NetworkExposure",
"ProcessPrivilege",
"MemoryProtection",
"SyscallAvailability"
],
"description": "Category of the assumption"
},
"key": {
"type": "string",
"description": "Identifier for what is being assumed (e.g., flag name, config key)"
},
"assumedValue": {
"type": "string",
"description": "The value being assumed"
},
"observedValue": {
"type": ["string", "null"],
"description": "The actually observed value, if verified"
},
"source": {
"type": "string",
"enum": ["Default", "StaticAnalysis", "RuntimeObservation", "UserProvided", "Inferred"],
"description": "How this assumption was derived"
},
"confidence": {
"type": "string",
"enum": ["Low", "Medium", "High", "Verified"],
"description": "Confidence level in this assumption"
}
},
"additionalProperties": false
},
"FalsifiabilityCriteria": {
"type": "object",
"description": "Criteria that would disprove or falsify the finding",
"required": ["id", "findingId", "generatedAt", "criteria"],
"properties": {
"id": {
"type": "string",
"description": "Unique identifier for this falsifiability assessment"
},
"findingId": {
"type": "string",
"description": "ID of the finding being assessed"
},
"generatedAt": {
"type": "string",
"format": "date-time",
"description": "When this assessment was generated"
},
"status": {
"type": "string",
"enum": ["Unknown", "Falsified", "NotFalsified", "PartiallyEvaluated"],
"description": "Overall falsifiability status"
},
"summary": {
"type": ["string", "null"],
"description": "Human-readable summary of falsifiability assessment"
},
"criteria": {
"type": "array",
"items": {
"$ref": "#/$defs/FalsificationCriterion"
},
"description": "Individual falsification criteria"
}
},
"additionalProperties": false
},
"FalsificationCriterion": {
"type": "object",
"description": "A single criterion that could falsify the finding",
"required": ["type", "description", "status"],
"properties": {
"type": {
"type": "string",
"enum": [
"PackageNotPresent",
"VersionMismatch",
"CodeUnreachable",
"FeatureDisabled",
"MitigationPresent",
"NoNetworkExposure",
"InsufficientPrivileges",
"PatchApplied",
"ConfigurationPrevents",
"RuntimePrevents"
],
"description": "Type of falsification criterion"
},
"description": {
"type": "string",
"description": "Human-readable description of what would falsify the finding"
},
"checkExpression": {
"type": ["string", "null"],
"description": "Machine-readable expression to check this criterion"
},
"evidence": {
"type": ["string", "null"],
"description": "Evidence supporting the criterion status"
},
"status": {
"type": "string",
"enum": ["Pending", "Satisfied", "NotSatisfied", "Inconclusive"],
"description": "Status of this criterion evaluation"
}
},
"additionalProperties": false
},
"EvidenceDensityScore": {
"type": "object",
"description": "Confidence score based on evidence density",
"required": ["score", "level"],
"properties": {
"score": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0,
"description": "Numeric confidence score (0.0 to 1.0)"
},
"level": {
"type": "string",
"enum": ["Low", "Medium", "High", "Verified"],
"description": "Confidence level tier"
},
"factorBreakdown": {
"type": "object",
"additionalProperties": {
"type": "number",
"minimum": 0.0,
"maximum": 1.0
},
"description": "Breakdown of contributing factors and their scores"
},
"explanation": {
"type": "string",
"description": "Human-readable explanation of the confidence assessment"
},
"improvementRecommendations": {
"type": "array",
"items": {
"type": "string"
},
"description": "Recommendations for improving confidence"
}
},
"additionalProperties": false
},
"RecommendedAction": {
"type": "object",
"description": "A recommended remediation action",
"required": ["priority", "action", "rationale", "effort"],
"properties": {
"priority": {
"type": "integer",
"minimum": 1,
"description": "Priority order (1 = highest)"
},
"action": {
"type": "string",
"description": "Description of the recommended action"
},
"rationale": {
"type": "string",
"description": "Why this action is recommended"
},
"effort": {
"type": "string",
"enum": ["Low", "Medium", "High"],
"description": "Estimated effort level"
}
},
"additionalProperties": false
}
}
}

View File

@@ -0,0 +1,149 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/trust-vector/1.0.0",
"title": "Trust Vector Schema",
"description": "Schema for 3-component trust vectors (Provenance, Coverage, Replayability)",
"type": "object",
"required": [
"provenance",
"coverage",
"replayability"
],
"properties": {
"provenance": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Provenance score (P): cryptographic and process integrity of the source"
},
"coverage": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Coverage score (C): how well the statement's scope maps to the target asset"
},
"replayability": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Replayability score (R): whether the claim can be deterministically re-derived"
}
},
"additionalProperties": false,
"$defs": {
"TrustWeights": {
"type": "object",
"description": "Weights for computing BaseTrust = wP*P + wC*C + wR*R",
"required": ["provenance", "coverage", "replayability"],
"properties": {
"provenance": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.45,
"description": "Weight for Provenance component (wP)"
},
"coverage": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.35,
"description": "Weight for Coverage component (wC)"
},
"replayability": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.20,
"description": "Weight for Replayability component (wR)"
}
},
"additionalProperties": false
},
"SourceClassDefaults": {
"type": "object",
"description": "Default trust vectors by source classification",
"properties": {
"vendor": {
"$ref": "#",
"description": "Default vector for vendor sources (P=0.90, C=0.70, R=0.60)"
},
"distro": {
"$ref": "#",
"description": "Default vector for distribution sources (P=0.80, C=0.85, R=0.60)"
},
"internal": {
"$ref": "#",
"description": "Default vector for internal sources (P=0.85, C=0.95, R=0.90)"
},
"hub": {
"$ref": "#",
"description": "Default vector for hub/aggregator sources (P=0.70, C=0.65, R=0.50)"
},
"attestation": {
"$ref": "#",
"description": "Default vector for attestation sources (P=0.95, C=0.80, R=0.95)"
}
},
"additionalProperties": {
"$ref": "#"
}
},
"ClaimStrength": {
"type": "string",
"enum": [
"exploitability_with_reachability",
"config_with_evidence",
"vendor_blanket",
"under_investigation"
],
"description": "Evidence-based claim strength categories"
},
"ClaimStrengthMultipliers": {
"type": "object",
"description": "Multiplier values for each claim strength category",
"properties": {
"exploitability_with_reachability": {
"type": "number",
"const": 1.00,
"description": "Exploitability analysis + reachability proof"
},
"config_with_evidence": {
"type": "number",
"const": 0.80,
"description": "Config/feature-flag reason with evidence"
},
"vendor_blanket": {
"type": "number",
"const": 0.60,
"description": "Vendor blanket statement"
},
"under_investigation": {
"type": "number",
"const": 0.40,
"description": "Under investigation status"
}
}
},
"FreshnessConfig": {
"type": "object",
"description": "Configuration for freshness decay calculation",
"properties": {
"half_life_days": {
"type": "number",
"minimum": 1,
"default": 90,
"description": "Days until score halves"
},
"floor": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.35,
"description": "Minimum freshness unless revoked"
}
},
"additionalProperties": false
}
}
}

View File

@@ -0,0 +1,228 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://stella-ops.org/schemas/verdict-manifest/1.0.0",
"title": "Verdict Manifest Schema",
"description": "Schema for DSSE-signed verdict manifests enabling deterministic replay and audit compliance",
"type": "object",
"required": [
"manifest_id",
"tenant",
"asset_digest",
"vulnerability_id",
"inputs",
"result",
"policy_hash",
"lattice_version",
"evaluated_at",
"manifest_digest"
],
"properties": {
"manifest_id": {
"type": "string",
"description": "Unique identifier for the verdict manifest",
"examples": ["verd:acme-corp:abc123:CVE-2025-12345:1703235600"]
},
"tenant": {
"type": "string",
"minLength": 1,
"description": "Tenant identifier for multi-tenancy"
},
"asset_digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 digest of the asset/SBOM"
},
"vulnerability_id": {
"type": "string",
"pattern": "^(CVE-[0-9]{4}-[0-9]+|GHSA-[a-z0-9-]+|[A-Z]+-[0-9]+)$",
"description": "Vulnerability identifier (CVE, GHSA, or vendor ID)"
},
"inputs": {
"$ref": "#/$defs/VerdictInputs"
},
"result": {
"$ref": "#/$defs/VerdictResult"
},
"policy_hash": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 hash of the policy file used"
},
"lattice_version": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+$",
"description": "Trust lattice version (semver format)"
},
"evaluated_at": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 UTC timestamp of evaluation"
},
"manifest_digest": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$",
"description": "SHA256 digest of the canonical manifest"
},
"signature_base64": {
"type": "string",
"description": "Base64-encoded DSSE signature (optional)"
},
"rekor_log_id": {
"type": "string",
"description": "Sigstore Rekor transparency log entry ID (optional)"
}
},
"additionalProperties": false,
"$defs": {
"VerdictInputs": {
"type": "object",
"description": "All inputs pinned for deterministic replay",
"required": [
"sbom_digests",
"vuln_feed_snapshot_ids",
"vex_document_digests",
"clock_cutoff"
],
"properties": {
"sbom_digests": {
"type": "array",
"items": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"description": "SHA256 digests of SBOM documents used"
},
"vuln_feed_snapshot_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Identifiers for vulnerability feed snapshots"
},
"vex_document_digests": {
"type": "array",
"items": {
"type": "string",
"pattern": "^sha256:[a-f0-9]{64}$"
},
"description": "SHA256 digests of VEX documents considered"
},
"reachability_graph_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Identifiers for call graph snapshots"
},
"clock_cutoff": {
"type": "string",
"format": "date-time",
"description": "Timestamp used for freshness calculations"
}
},
"additionalProperties": false
},
"VerdictResult": {
"type": "object",
"description": "The verdict outcome with full explanation",
"required": [
"status",
"confidence",
"explanations"
],
"properties": {
"status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "Final VEX status"
},
"confidence": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Confidence score (0.0 to 1.0)"
},
"explanations": {
"type": "array",
"items": {
"$ref": "#/$defs/VerdictExplanation"
},
"description": "Per-source breakdown of scoring"
},
"evidence_refs": {
"type": "array",
"items": {
"type": "string"
},
"description": "Links to attestations and proof bundles"
}
},
"additionalProperties": false
},
"VerdictExplanation": {
"type": "object",
"description": "Explanation of a single claim's contribution to the verdict",
"required": [
"source_id",
"reason",
"claim_score"
],
"properties": {
"source_id": {
"type": "string",
"description": "Identifier of the VEX source"
},
"reason": {
"type": "string",
"description": "Human-readable reason for the claim"
},
"provenance_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Provenance (P) component score"
},
"coverage_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Coverage (C) component score"
},
"replayability_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Replayability (R) component score"
},
"strength_multiplier": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Claim strength multiplier (M)"
},
"freshness_multiplier": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Freshness decay multiplier (F)"
},
"claim_score": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Final claim score: BaseTrust * M * F"
},
"asserted_status": {
"type": "string",
"enum": ["affected", "not_affected", "fixed", "under_investigation"],
"description": "Status asserted by this claim"
},
"accepted": {
"type": "boolean",
"description": "Whether this claim was accepted as the winner"
}
},
"additionalProperties": false
}
}
}