{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://diditwork.org/schema/site_index.schema.json",
  "title": "Did it work? site index v1",
  "description": "Machine-readable index of every donor page on diditwork.org, served at https://diditwork.org/agents/site-index.json and regenerated from repo data on every build. Every figure is a verified evaluator claim with its source URL; figures are modeled, not guaranteed, and paid placement never affects anything here.",
  "type": "object",
  "required": [
    "schema",
    "site",
    "note",
    "api",
    "feed",
    "charities",
    "causes",
    "ledger",
    "interventions"
  ],
  "additionalProperties": false,
  "properties": {
    "$schema": {
      "type": "string",
      "const": "https://diditwork.org/schema/site_index.schema.json",
      "description": "This schema's URL."
    },
    "schema": {
      "const": "diditwork.site-index/v1",
      "description": "Format name and major version."
    },
    "site": {
      "const": "https://diditwork.org",
      "description": "Site origin."
    },
    "note": {
      "type": "string",
      "description": "Plain-language rules for using the figures."
    },
    "api": {
      "type": "object",
      "description": "API, MCP and OpenAPI URLs.",
      "required": [
        "base",
        "mcp",
        "openapi"
      ],
      "additionalProperties": false,
      "properties": {
        "base": {
          "$ref": "#/$defs/url"
        },
        "mcp": {
          "$ref": "#/$defs/url"
        },
        "openapi": {
          "$ref": "#/$defs/url"
        }
      }
    },
    "feed": {
      "$ref": "#/$defs/url",
      "description": "Atom feed of changes to figures and pages."
    },
    "charities": {
      "type": "array",
      "description": "One entry per charity page.",
      "items": {
        "$ref": "#/$defs/charity"
      }
    },
    "causes": {
      "type": "array",
      "description": "One entry per cause page.",
      "items": {
        "type": "object",
        "required": [
          "id",
          "title",
          "url",
          "charity_ids"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^cause_[a-z0-9_]+$"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "$ref": "#/$defs/url"
          },
          "charity_ids": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/org_id"
            }
          }
        }
      }
    },
    "ledger_head": {
      "type": "object",
      "description": "Tamper evidence for the outcome ledger: record count and the SHA-256 of the newest record, which chains every earlier record. The same value is served by GET https://api.diditwork.org/v1/meta (ledger.head_sha256).",
      "required": [
        "count",
        "head_sha256",
        "pinned_on",
        "page",
        "api",
        "note"
      ],
      "additionalProperties": false,
      "properties": {
        "count": {
          "type": "integer",
          "minimum": 0
        },
        "head_sha256": {
          "$ref": "#/$defs/sha256"
        },
        "pinned_on": {
          "$ref": "#/$defs/date"
        },
        "page": {
          "$ref": "#/$defs/url"
        },
        "api": {
          "$ref": "#/$defs/url"
        },
        "note": {
          "type": "string"
        }
      }
    },
    "comparisons": {
      "type": "array",
      "description": "Side-by-side pages. Only two charities rated by the same evaluator in the same unit for the same period; no derived figures and no winner.",
      "items": {
        "type": "object",
        "required": [
          "url",
          "title",
          "evaluator",
          "unit",
          "period",
          "charity_ids",
          "claim_ids",
          "rule"
        ],
        "additionalProperties": false,
        "properties": {
          "url": {
            "$ref": "#/$defs/url"
          },
          "title": {
            "type": "string"
          },
          "evaluator": {
            "$ref": "#/$defs/evaluator"
          },
          "unit": {
            "enum": [
              "USD_per_life_saved",
              "WELLBY_per_1000_USD"
            ]
          },
          "period": {
            "type": "string"
          },
          "charity_ids": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/org_id"
            },
            "minItems": 2,
            "maxItems": 2
          },
          "claim_ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 2,
            "maxItems": 2
          },
          "rule": {
            "type": "string"
          }
        }
      }
    },
    "questions": {
      "type": "array",
      "description": "Donor question pages (\"What's the best charity for malaria?\"). The shortlist is the cause's charities with an evaluator's top or promising designation, in cause-page order; no ranking, no derived figures, no winner.",
      "items": {
        "type": "object",
        "required": [
          "url",
          "question",
          "cause_id",
          "answer",
          "charity_ids",
          "claim_ids",
          "comparisons",
          "funds",
          "rule"
        ],
        "additionalProperties": false,
        "properties": {
          "url": {
            "$ref": "#/$defs/url"
          },
          "question": {
            "type": "string"
          },
          "cause_id": {
            "type": "string",
            "pattern": "^cause_[a-z0-9_]+$"
          },
          "answer": {
            "type": "string"
          },
          "charity_ids": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/org_id"
            },
            "minItems": 1
          },
          "claim_ids": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "comparisons": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/url"
            }
          },
          "funds": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/org_id"
            }
          },
          "rule": {
            "type": "string"
          }
        }
      }
    },
    "ledger": {
      "type": "array",
      "description": "One entry per follow-up record page (outcome-ledger claim_snapshot).",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "record_id",
          "url",
          "api",
          "org_id",
          "evaluator",
          "claim_id",
          "value",
          "unit",
          "display",
          "recorded_on",
          "check_after",
          "status",
          "record_sha256",
          "modeled",
          "guaranteed"
        ],
        "properties": {
          "record_id": {
            "type": "string",
            "pattern": "^ldg_[a-z0-9_]+$"
          },
          "url": {
            "$ref": "#/$defs/url"
          },
          "api": {
            "$ref": "#/$defs/url"
          },
          "org_id": {
            "$ref": "#/$defs/org_id"
          },
          "evaluator": {
            "$ref": "#/$defs/evaluator"
          },
          "claim_id": {
            "type": "string"
          },
          "value": {
            "type": "number"
          },
          "unit": {
            "type": "string"
          },
          "display": {
            "type": "string"
          },
          "recorded_on": {
            "$ref": "#/$defs/date"
          },
          "check_after": {
            "$ref": "#/$defs/date"
          },
          "status": {
            "enum": [
              "pending",
              "confirmed",
              "contradicted",
              "unverifiable"
            ]
          },
          "record_sha256": {
            "$ref": "#/$defs/sha256"
          },
          "modeled": {
            "type": "boolean"
          },
          "guaranteed": {
            "const": false
          }
        }
      }
    },
    "interventions": {
      "type": "array",
      "description": "One entry per approach page.",
      "items": {
        "type": "object",
        "required": [
          "id",
          "title",
          "url",
          "evidence",
          "citations"
        ],
        "additionalProperties": false,
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^int_[a-z0-9_]+$"
          },
          "title": {
            "type": "string"
          },
          "url": {
            "$ref": "#/$defs/url"
          },
          "evidence": {
            "$ref": "#/$defs/evidence"
          },
          "citations": {
            "type": "array",
            "items": {
              "$ref": "#/$defs/url"
            }
          }
        }
      }
    },
    "claims": {
      "type": "object",
      "description": "Where to get every published figure in the open impact-claim/v0 format.",
      "required": [
        "all",
        "standard",
        "spec"
      ],
      "additionalProperties": false,
      "properties": {
        "all": {
          "$ref": "#/$defs/url"
        },
        "standard": {
          "const": "impact-claim/v0"
        },
        "spec": {
          "$ref": "#/$defs/url"
        },
        "note": {
          "type": "string"
        }
      }
    }
  },
  "$defs": {
    "url": {
      "type": "string",
      "pattern": "^https://"
    },
    "sha256": {
      "type": "string",
      "pattern": "^[0-9a-f]{64}$"
    },
    "date": {
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "org_id": {
      "type": "string",
      "pattern": "^org_[a-z0-9_]+$"
    },
    "evaluator": {
      "enum": [
        "GiveWell",
        "Happier Lives Institute",
        "Animal Charity Evaluators",
        "World Health Organization",
        "Institute for Health Metrics and Evaluation"
      ]
    },
    "evidence": {
      "oneOf": [
        {
          "type": "null"
        },
        {
          "type": "object",
          "required": [
            "label",
            "rated_by"
          ],
          "additionalProperties": false,
          "properties": {
            "label": {
              "type": "string"
            },
            "rated_by": {
              "$ref": "#/$defs/evaluator"
            }
          }
        }
      ]
    },
    "figure": {
      "type": "object",
      "description": "A published evaluator figure, copied exactly.",
      "required": [
        "claim_id",
        "label",
        "value",
        "unit",
        "display",
        "period",
        "evaluator",
        "source_url",
        "modeled",
        "guaranteed"
      ],
      "additionalProperties": false,
      "properties": {
        "claim_id": {
          "type": "string"
        },
        "label": {
          "type": "string"
        },
        "value": {
          "type": "number"
        },
        "unit": {
          "type": "string"
        },
        "display": {
          "type": "string"
        },
        "period": {
          "type": "string"
        },
        "evaluator": {
          "$ref": "#/$defs/evaluator"
        },
        "source_url": {
          "$ref": "#/$defs/url"
        },
        "modeled": {
          "type": "boolean"
        },
        "guaranteed": {
          "const": false,
          "description": "Always false: estimates are never promises."
        }
      }
    },
    "charity": {
      "type": "object",
      "required": [
        "id",
        "name",
        "url",
        "embed",
        "designation",
        "evaluator",
        "evidence",
        "figures",
        "api"
      ],
      "additionalProperties": false,
      "properties": {
        "id": {
          "$ref": "#/$defs/org_id"
        },
        "name": {
          "type": "string"
        },
        "url": {
          "$ref": "#/$defs/url"
        },
        "embed": {
          "$ref": "#/$defs/url"
        },
        "designation": {
          "type": "string"
        },
        "evaluator": {
          "$ref": "#/$defs/evaluator"
        },
        "evidence": {
          "$ref": "#/$defs/evidence"
        },
        "figures": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/figure"
          }
        },
        "api": {
          "$ref": "#/$defs/url"
        },
        "claims": {
          "$ref": "#/$defs/url",
          "description": "This charity's published figures as impact-claim/v0 claims (present when the page shows at least one figure)."
        }
      }
    }
  }
}
