{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://docs.imboard.ai/api/ontology/schema.json",
  "title": "I'mBoard Board Ontology — response schema",
  "description": "Generated from the OntologyResponse / OntologyDomainResponse / OntologyKpiResponse TypeScript types in @imboard/shared-types. Validate /api/ontology/index.json against #/definitions/OntologyResponse, /api/ontology/{domain}.json against #/definitions/OntologyDomainResponse, and /api/ontology/{domain}/{slug}.json against #/definitions/OntologyKpiResponse.",
  "definitions": {
    "OntologyResponse": {
      "type": "object",
      "properties": {
        "version": {
          "type": "string"
        },
        "releasedAt": {
          "type": "string"
        },
        "kpis": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/OntologyKpi"
          }
        }
      },
      "required": [
        "kpis",
        "releasedAt",
        "version"
      ],
      "additionalProperties": false
    },
    "OntologyKpi": {
      "type": "object",
      "properties": {
        "rogueId": {
          "type": "string"
        },
        "slug": {
          "type": "string"
        },
        "domain": {
          "type": "string"
        },
        "defaultLabel": {
          "type": "string"
        },
        "description": {
          "type": "string"
        },
        "fieldType": {
          "type": "string"
        },
        "unit": {
          "type": [
            "string",
            "null"
          ]
        },
        "maturity": {
          "type": "string"
        },
        "suggestedForStages": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/CompanyStageType"
          }
        },
        "defaultOwningFunctions": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "stageRelevance": {
          "$ref": "#/definitions/Record%3Cstring%2CRogueKpiPriorityType%3E"
        },
        "definitionSource": {
          "$ref": "#/definitions/OntologyDefinitionSource"
        },
        "benchmark": {
          "$ref": "#/definitions/OntologyBenchmark"
        },
        "formula": {
          "type": "string"
        },
        "whyItMatters": {
          "type": "string"
        },
        "interpretationGuidance": {
          "type": "string"
        },
        "relatedKpiIds": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "calculationPolicy": {
          "$ref": "#/definitions/OntologyCalculationPolicy"
        },
        "metricBasis": {
          "$ref": "#/definitions/OntologyMetricBasis"
        }
      },
      "required": [
        "rogueId",
        "slug",
        "domain",
        "defaultLabel",
        "description",
        "fieldType",
        "unit",
        "maturity",
        "suggestedForStages",
        "defaultOwningFunctions",
        "stageRelevance",
        "definitionSource"
      ],
      "additionalProperties": false,
      "description": "The public ontology shape. Both surfaces (runtime backend + docs build) emit exactly this. Optional fields are emitted only when populated to keep the JSON lean for unenriched KPIs."
    },
    "CompanyStageType": {
      "type": "string",
      "enum": [
        "preSeed",
        "seed",
        "seriesA",
        "seriesB",
        "seriesC",
        "public"
      ]
    },
    "Record<string,RogueKpiPriorityType>": {
      "type": "object",
      "additionalProperties": {
        "$ref": "#/definitions/RogueKpiPriorityType"
      }
    },
    "RogueKpiPriorityType": {
      "type": "string",
      "enum": [
        "core",
        "recommended",
        "available"
      ]
    },
    "OntologyDefinitionSource": {
      "type": "object",
      "properties": {
        "tier": {
          "$ref": "#/definitions/RogueKpiDefinitionTierType"
        },
        "sourceName": {
          "type": "string"
        },
        "sourceUrl": {
          "type": [
            "string",
            "null"
          ]
        },
        "sectionRef": {
          "type": [
            "string",
            "null"
          ]
        },
        "publicationDate": {
          "type": "string"
        },
        "attributionNotice": {
          "type": [
            "string",
            "null"
          ]
        }
      },
      "required": [
        "tier",
        "sourceName",
        "sourceUrl",
        "sectionRef",
        "publicationDate",
        "attributionNotice"
      ],
      "additionalProperties": false
    },
    "RogueKpiDefinitionTierType": {
      "type": "string",
      "enum": [
        "published",
        "editorial"
      ]
    },
    "OntologyBenchmark": {
      "type": "object",
      "properties": {
        "p25": {
          "type": "number"
        },
        "median": {
          "type": "number"
        },
        "p75": {
          "type": "number"
        },
        "unit": {
          "type": "string"
        },
        "sourceName": {
          "type": "string"
        },
        "sourceYear": {
          "type": "string"
        },
        "higherIsBetter": {
          "type": "boolean"
        }
      },
      "required": [
        "p25",
        "median",
        "p75",
        "unit",
        "sourceName",
        "sourceYear",
        "higherIsBetter"
      ],
      "additionalProperties": false,
      "description": "Reference distribution attached to ontology + MCP KPI responses. Structurally identical to the backend's `PublicBenchmarkSummary`; the backend keeps that alias for back-compat but it is now a re-export of this canonical shape."
    },
    "OntologyCalculationPolicy": {
      "type": "object",
      "properties": {
        "inclusionRules": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "exclusionRules": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "requiredInputs": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "dataSourcePriority": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "edgeCases": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "validationChecks": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "commonMiscomputations": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "additionalProperties": false,
      "description": "Per-KPI agent-safe computation contract (#1483 / v1.1.0).\n\nThe narrative `description`, `formula`, and `interpretationGuidance` fields tell humans *what* a metric means. `calculationPolicy` tells an AI agent\n*how* to compute it correctly from a company's messy data — what to include/exclude, what inputs are required, what data sources to prefer, what edge cases to handle, what validations to apply, and (highest leverage) what common miscomputations to avoid.\n\nFree-text strings only — the audience is LLM agents at reasoning time, not a deterministic computation engine. A structured DSL would force premature formalization; revisit only when deterministic consumers materialize.\n\nAll subfields optional; emitted only when non-empty so unenriched KPIs keep a lean public JSON footprint. Most KPIs in v1.1.0 carry no policy; a curated set of high-leverage KPIs do — the canonical list of seeded rogueIds lives in the seed unit test (`seeds exactly the N high-leverage KPIs`), which is the single source of truth so the methodology page, changelog, and seed file cannot drift independently.\n\nEach editorial→published promotion (epic #1415) is a natural moment to populate this block."
    },
    "OntologyMetricBasis": {
      "type": "object",
      "properties": {
        "timeBasis": {
          "type": "string",
          "enum": [
            "point_in_time",
            "period_flow",
            "trailing_window"
          ],
          "description": "When the value is measured."
        },
        "moneyBasis": {
          "type": "string",
          "enum": [
            "contracted_arr",
            "recognized_revenue",
            "cash",
            "bookings"
          ],
          "description": "Which kind of money — monetary KPIs only. `fieldType` already says \"currency\"; this says WHICH money, a distinction `fieldType` cannot express. Omitted for non-monetary KPIs and for pipeline/forecast/ valuation amounts (which are none of these realized money-kinds)."
        },
        "cohortBasis": {
          "type": "string",
          "enum": [
            "closed_start_cohort",
            "all_active"
          ],
          "description": "Cohort definition — cohort-based metrics (retention) only."
        },
        "dateBasis": {
          "type": "string",
          "enum": [
            "go_live",
            "signed",
            "period_close"
          ],
          "description": "Which contract event qualifies a record — the ARR/bookings family only."
        },
        "production": {
          "type": "string",
          "enum": [
            "computed",
            "primary"
          ],
          "description": "How the value is produced: `computed` (a deterministic function of other Rogue KPIs — ratios, rollups, waterfall-derived) vs `primary` (a raw measurement a human or source system enters). An agent uses this to decide \"compute this\" vs \"fetch this\". Not inferable from `formula`, which is populated on every KPI."
        }
      },
      "additionalProperties": false,
      "description": "Structured, machine-filterable measurement metadata for a KPI (#1494 / v1.3.0).\n\nWhere `calculationPolicy` is free-text guidance for an LLM, `metricBasis` is a small set of enum axes a consumer can filter and reason on deterministically — \"give me all point-in-time metrics\", \"all cohort-based metrics\", \"all metrics measured on a cash basis\".\n\nEvery sub-field is independently optional and omitted when not meaningful (the `calculationPolicy` pattern). The axes have very different applicability: `timeBasis` / `production` are near-universal among numeric KPIs; `moneyBasis` applies only to monetary KPIs; `dateBasis` only to the ARR/bookings family; `cohortBasis` only to retention metrics. A KPI carries only the axes that mean something for it — there is deliberately no `not_applicable` value. Narrative (`fieldType: 'text'`) KPIs carry no `metricBasis` at all."
    },
    "OntologyDomainResponse": {
      "type": "object",
      "properties": {
        "version": {
          "type": "string"
        },
        "releasedAt": {
          "type": "string"
        },
        "domain": {
          "type": "string"
        },
        "kpis": {
          "type": "array",
          "items": {
            "$ref": "#/definitions/OntologyKpi"
          }
        }
      },
      "required": [
        "domain",
        "kpis",
        "releasedAt",
        "version"
      ],
      "additionalProperties": false
    },
    "OntologyKpiResponse": {
      "type": "object",
      "properties": {
        "version": {
          "type": "string"
        },
        "releasedAt": {
          "type": "string"
        },
        "kpi": {
          "$ref": "#/definitions/OntologyKpi"
        }
      },
      "required": [
        "kpi",
        "releasedAt",
        "version"
      ],
      "additionalProperties": false
    }
  }
}
