{
  "openapi": "3.1.0",
  "info": {
    "title": "Daritas Automation Continuity API",
    "version": "1.0.0",
    "description": "Read-only, advisory access to your verified control-system model — the same evidence-backed facts the app shows, scoped to your organization by API key. Nothing here instructs a control action."
  },
  "servers": [
    {
      "url": "https://assess.daritas.com",
      "description": "Daritas"
    }
  ],
  "tags": [
    {
      "name": "Index",
      "description": "Discovery and key check."
    },
    {
      "name": "Assessments",
      "description": "Read the verified model: assessments, behaviours, governed context, drift."
    },
    {
      "name": "AI governance",
      "description": "Record what your own AI systems did, and what AI exposure a floor scan found."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer <your key>"
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "X-API-Key: <your key>"
      }
    }
  },
  "paths": {
    "/api/v1": {
      "get": {
        "operationId": "index",
        "tags": [
          "Index"
        ],
        "summary": "API index",
        "description": "Lists the available endpoints. Key-authenticated, so it doubles as a cheap \"is my key live?\" check.",
        "responses": {
          "200": {
            "description": "The endpoint index.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "product": "Daritas — Automation Continuity read API (v1)",
                  "note": "Read-only, advisory. Every response is scoped to your organization.",
                  "endpoints": {
                    "GET /api/v1/assessments": "List your assessments (id, title, status, latest version)."
                  },
                  "auth": "Authorization: Bearer <your key>  (or  X-API-Key: <your key>)"
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments": {
      "get": {
        "operationId": "list-assessments",
        "tags": [
          "Assessments"
        ],
        "summary": "List assessments",
        "description": "Every assessment in your organization, newest first, with the version number and counts of its latest model baseline.",
        "responses": {
          "200": {
            "description": "Your assessments.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "assessments": [
                    {
                      "id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                      "title": "AHU-1 air handling unit",
                      "status": "delivered",
                      "latest_version": 3,
                      "counts": {
                        "nodes": 201,
                        "edges": 344,
                        "behaviours": 68
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments/{id}": {
      "get": {
        "operationId": "get-assessment",
        "tags": [
          "Assessments"
        ],
        "summary": "Get one assessment",
        "description": "One assessment with the system it is of, its latest model version, the counts in that baseline and the mean confidence.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The assessment id.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "responses": {
          "200": {
            "description": "The assessment.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                  "title": "AHU-1 air handling unit",
                  "status": "delivered",
                  "system_name": "AHU-1",
                  "version": 3,
                  "generated_at": "2026-07-18T09:14:02.000Z",
                  "counts": {
                    "nodes": 201,
                    "edges": 344,
                    "behaviours": 68
                  },
                  "confidence": {
                    "mean": 0.82
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "No such assessment in your organization. (Same answer whether it does not exist or belongs to someone else — the API never discloses another org.)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "No such assessment in your organization."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments/{id}/behaviours": {
      "get": {
        "operationId": "get-behaviours",
        "tags": [
          "Assessments"
        ],
        "summary": "Get grounded behaviours",
        "description": "The behaviours in the latest baseline. Each carries the evidence it was grounded in (source file, locator, quote), the extraction confidence, and the human review status.\n\n`review_status` is one of **confirmed** · **corrected** · **uncertain** · **inconclusive** · **flagged** · **unverified**.\n\nTwo of those are open questions a human left behind, and neither may be relied on as fact:\n- **uncertain** — a reviewer believes the statement but recorded that they could not be certain of it.\n- **inconclusive** — a reviewer read it and the available sources could not settle it either way. Not a defect and not a doubt about the plant; a limit of the material, and the clearest thing to go and ask about.\n\nBoth are deliberately kept out of `confirmed` (which would overstate them) and out of `unverified` (which would throw away that a human read it and left a judgement).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The assessment id.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "responses": {
          "200": {
            "description": "Behaviours for the latest model version. `version` is null and the list empty when no baseline has been loaded yet.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "version": 3,
                  "behaviours": [
                    {
                      "claim_id": "B-014",
                      "statement": "The heating valve opens when supply air falls more than 2 °C below setpoint.",
                      "subjects": [
                        "HeatValve",
                        "SupplyTemp"
                      ],
                      "function": "temperature-control",
                      "confidence": 0.86,
                      "state": "grounded",
                      "safety_relevant": false,
                      "review_status": "confirmed",
                      "evidence": [
                        {
                          "sourceRef": {
                            "file": "AHU1_Main.st",
                            "locator": "lines 412-418"
                          },
                          "quote": "IF SupplyTemp < SetPoint - 2.0 THEN HeatValve := TRUE;"
                        }
                      ]
                    },
                    {
                      "claim_id": "B-031",
                      "statement": "The supply fan runs on for 90 s after shutdown.",
                      "subjects": [
                        "SupplyFan"
                      ],
                      "function": "fan-control",
                      "confidence": 0.61,
                      "state": "aiInferred",
                      "safety_relevant": false,
                      "review_status": "uncertain",
                      "evidence": [
                        {
                          "sourceRef": {
                            "file": "AHU1_Main.st",
                            "locator": "lines 412-418"
                          },
                          "quote": "IF SupplyTemp < SetPoint - 2.0 THEN HeatValve := TRUE;"
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "No such assessment in your organization. (Same answer whether it does not exist or belongs to someone else — the API never discloses another org.)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "No such assessment in your organization."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments/{id}/context": {
      "get": {
        "operationId": "get-context",
        "tags": [
          "Assessments"
        ],
        "summary": "Get the governed AI context",
        "description": "A bounded context pack built for feeding an AI copilot: the verified facts it may rely on, the known-unknowns it must not assert, the approved evidence sources, coverage numbers, and the usage policy the model is served under. Prefer this over the raw behaviours when an AI is doing the reading.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The assessment id.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "responses": {
          "200": {
            "description": "The governed context pack.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "assessment": {
                    "id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                    "title": "AHU-1 air handling unit",
                    "system": "AHU-1",
                    "model_version": 3,
                    "generated_at": "2026-07-18T09:14:02.000Z"
                  },
                  "usage_policy": {
                    "read_only": true,
                    "advisory_only": true,
                    "must_cite_evidence": true,
                    "must_flag_unknowns": true,
                    "no_control_actions": true,
                    "note": "Rely only on verified_behaviours. Treat known_unknowns as UNCONFIRMED — do not assert them as fact. Always cite the evidence file/locator…"
                  },
                  "coverage": {
                    "total": 68,
                    "verified": 41,
                    "unverified": 27,
                    "safety_total": 9,
                    "safety_verified": 9,
                    "coverage_pct": 60
                  },
                  "approved_sources": [
                    "AHU1_Main.st",
                    "AHU1_Alarms.st"
                  ],
                  "verified_behaviours": [
                    {
                      "claim_id": "B-014",
                      "statement": "The heating valve opens when supply air falls more than 2 °C below setpoint.",
                      "function": "temperature-control",
                      "safety_relevant": false,
                      "confidence": 0.86,
                      "evidence": [
                        {
                          "sourceRef": {
                            "file": "AHU1_Main.st",
                            "locator": "lines 412-418"
                          },
                          "quote": "IF SupplyTemp < SetPoint - 2.0 THEN HeatValve := TRUE;"
                        }
                      ]
                    }
                  ],
                  "known_unknowns": [
                    {
                      "claim_id": "B-052",
                      "statement": "Night setback is disabled while the fire damper is open.",
                      "function": "scheduling",
                      "safety_relevant": true,
                      "confidence": 0.41,
                      "evidence": [],
                      "review_status": "unverified",
                      "state": "inferred",
                      "caveat": "Not human-verified — do not assert as fact."
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "No such assessment in your organization. (Same answer whether it does not exist or belongs to someone else — the API never discloses another org.)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "No such assessment in your organization."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments/{id}/changes": {
      "get": {
        "operationId": "get-changes",
        "tags": [
          "Assessments"
        ],
        "summary": "Get drift between baselines",
        "description": "What moved between the two latest model versions — behaviours added, removed and changed — and, importantly, which human sign-offs those changes invalidated. With a single baseline the diff is empty and `note` says so.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The assessment id.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "responses": {
          "200": {
            "description": "The diff between the two latest versions.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "from": 2,
                  "to": 3,
                  "unchanged": 61,
                  "invalidated_signoffs": 2,
                  "changed": [
                    {
                      "claim_id": "B-014",
                      "statement": "The heating valve opens when supply air falls more than 2 °C below setpoint.",
                      "safety_relevant": false,
                      "statement_changed": true,
                      "evidence_changed": false,
                      "was_verified": true
                    }
                  ],
                  "added": [
                    {
                      "claim_id": "B-069",
                      "statement": "A filter-blocked alarm latches until acknowledged.",
                      "safety_relevant": false
                    }
                  ],
                  "removed": [
                    {
                      "claim_id": "B-031",
                      "statement": "Fan runs on after shutdown for 90 s.",
                      "safety_relevant": false,
                      "was_verified": true
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "No such assessment in your organization. (Same answer whether it does not exist or belongs to someone else — the API never discloses another org.)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "No such assessment in your organization."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments/{id}/baselines": {
      "get": {
        "operationId": "list-baselines",
        "tags": [
          "Assessments"
        ],
        "summary": "List baselines and their archived content",
        "description": "Every analysed state of the system, newest first. `project_sha256` is the baseline’s identity — a hash over the exact source files analysed — and `pack` says whether the full Continuity Pack for it is archived.\n\n**Why this exists.** The queryable model is a lossy projection: it drops the proposals the evidence guard rejected, the coverage record and the symbol index. An attestation binds to artifact hashes and an auditor may be handed a `project_sha256`, so the bytes those name have to still exist. Download the pack and check it yourself with `daritas archive --verify <file.tgz>`, which recomputes the identity from the archived source inventory.\n\n**`pack.status`** is one of:\n- **stored** — archived; `download_url` is a short-lived link to it.\n- **withheld** — you ran this assessment on your own machine and the content never left your network. A deliberate absence, not a loss.\n- **unavailable** — we do not have it, so this baseline cannot be reproduced or independently checked. Baselines produced before archiving existed are in this state.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The assessment id.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "responses": {
          "200": {
            "description": "The assessment’s baselines.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "baselines": [
                    {
                      "version": 3,
                      "system": "AHU-1",
                      "generated_at": "2026-07-18T09:14:02.000Z",
                      "counts": {
                        "nodes": 201,
                        "edges": 344,
                        "claims": 68
                      },
                      "project_sha256": "27e4b9d1f1706810090d1f742b84eb08719becc23be0ea364745dee689d53ffa",
                      "pack": {
                        "status": "stored",
                        "note": "The full Continuity Pack for this baseline is archived and can be downloaded and verified.",
                        "sha256": "3df385c755a7756745fe0e4bf517317999d574bfb16e13dc95d0df66724950de",
                        "bytes": 28438,
                        "archived_at": "2026-07-18T09:14:40.000Z",
                        "download_url": "https://…/storage/v1/object/sign/…"
                      }
                    },
                    {
                      "version": 2,
                      "system": "AHU-1",
                      "generated_at": "2026-06-02T11:03:00.000Z",
                      "counts": {
                        "nodes": 198,
                        "edges": 340,
                        "claims": 66
                      },
                      "project_sha256": null,
                      "pack": {
                        "status": "unavailable",
                        "note": "The Continuity Pack for this baseline was not archived, so its content cannot be reproduced or independently checked. Baselines produced before archiving existed are in this state.",
                        "sha256": null,
                        "bytes": null,
                        "archived_at": null,
                        "download_url": null
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "No such assessment in your organization. (Same answer whether it does not exist or belongs to someone else — the API never discloses another org.)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "No such assessment in your organization."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/assessments/{id}/model": {
      "post": {
        "operationId": "push-model",
        "tags": [
          "Assessments"
        ],
        "summary": "Sync a model produced on your own machine",
        "description": "Local mode. You ran the assessment yourself (`daritas ingest`) and are choosing to sync the result so colleagues can open it in the portal. Stored as the assessment’s next model version. **Your source files are never sent** — the body is the model. It does carry the verbatim excerpt each claim cites, because a claim is only accepted when its quote appears in your source; `daritas push --no-quotes` withholds those excerpts and keeps the citations alone, and sets `quotes: \"withheld\"` so the portal labels them rather than showing an empty box. The CLI prints the exact, counted disclosure before it sends.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The assessment id.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "requestBody": {
          "required": true,
          "description": "The model out of a Continuity Pack: `manifest`, `nodes[]`, `edges[]`, `claims[]`, optional `xref[]`. Up to 100,000 nodes and claims per push.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "manifest": {
                  "system": "AHU-01",
                  "tool": "daritas",
                  "toolVersion": "0.0.0",
                  "modelVersion": "0.1",
                  "generatedAt": "2026-07-29T09:12:04.000Z",
                  "counts": {
                    "nodes": 106,
                    "edges": 118,
                    "claims": 185,
                    "evidence": 185,
                    "sources": 10
                  },
                  "confidence": {
                    "mean": 0.78,
                    "min": 0.4,
                    "max": 0.95
                  }
                },
                "nodes": [
                  {
                    "id": "sensor:TT01",
                    "kind": "sensor",
                    "name": "TT01",
                    "attrs": {},
                    "evidence": []
                  }
                ],
                "edges": [
                  {
                    "from": "system:AHU-01",
                    "to": "sensor:TT01",
                    "kind": "partOf"
                  }
                ],
                "claims": [
                  {
                    "id": "clm:1",
                    "statement": "TT01 reads supply air temperature.",
                    "subjects": [
                      "sensor:TT01"
                    ],
                    "confidence": 0.9,
                    "state": "sourceSupported",
                    "evidence": [
                      {
                        "sourceRef": {
                          "file": "AHU1_Main.st",
                          "locator": "lines 412-418"
                        },
                        "quote": "IF SupplyTemp < SetPoint - 2.0 THEN HeatValve := TRUE;"
                      }
                    ]
                  }
                ],
                "quotes": "included"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Stored as a new model version. Open it at `url`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "model_version_id": "b41c9e02-77a1-4f7e-9d21-0c5b3a8e9f14",
                  "version": 3,
                  "url": "/customer/orders/8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5/model",
                  "stored": {
                    "nodes": 106,
                    "edges": 118,
                    "claims": 185
                  },
                  "quotes": "included"
                }
              }
            }
          },
          "400": {
            "description": "Body was not JSON, or did not carry a model.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "bad_request",
                  "message": "Body must carry nodes[], edges[] and claims[] — the model from a Continuity Pack."
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "No such assessment in your organization. (Same answer whether it does not exist or belongs to someone else — the API never discloses another org.)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "No such assessment in your organization."
                }
              }
            }
          },
          "413": {
            "description": "More nodes/edges/claims than one push accepts.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "too_large",
                  "message": "250000 claims exceeds the 100000 we accept in one push. Split the assessment, or talk to us — this is a limit we can raise for a real system."
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/ai-events": {
      "get": {
        "operationId": "list-ai-events",
        "tags": [
          "AI governance"
        ],
        "summary": "Read the AI runtime ledger",
        "description": "Your organization’s AI event ledger, newest first (up to 200).",
        "parameters": [
          {
            "name": "assessment_id",
            "in": "query",
            "required": false,
            "description": "Restrict to one assessment. Omit for the whole organization.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          }
        ],
        "responses": {
          "200": {
            "description": "Recorded AI events.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "events": [
                    {
                      "id": "3a9c1f80-6b2d-4d51-8b0a-1f7d2c3e4a55",
                      "job_id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                      "source": "hmi-copilot",
                      "actor": "operator:erik",
                      "model": "claude-opus-5",
                      "prompt": "Why did AHU-1 trip last night?",
                      "response": "The filter-blocked alarm latched at 02:14…",
                      "action": "advisory",
                      "influence_level": "L1",
                      "approved_by": null,
                      "linked_behaviour": "B-069",
                      "created_at": "2026-07-19T02:31:44.000Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "record-ai-event",
        "tags": [
          "AI governance"
        ],
        "summary": "Record an AI event",
        "description": "Append one AI event from your own AI systems (HMI copilot, agent, edge assistant) to the auditable runtime ledger. Every field is optional — record what you have. `assessment_id`, when given, must belong to your organization.",
        "requestBody": {
          "required": true,
          "description": "The event. Unknown fields are ignored; `metadata` takes any JSON you want to keep alongside it.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "source": "hmi-copilot",
                "actor": "operator:erik",
                "model": "claude-opus-5",
                "prompt": "Why did AHU-1 trip last night?",
                "response": "The filter-blocked alarm latched at 02:14…",
                "action": "advisory",
                "influence_level": "L1",
                "approved_by": null,
                "assessment_id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                "linked_behaviour": "B-069",
                "metadata": {
                  "session": "abc-123"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Recorded.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "id": "3a9c1f80-6b2d-4d51-8b0a-1f7d2c3e4a55",
                  "recorded": true
                }
              }
            }
          },
          "400": {
            "description": "The body was not JSON.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "bad_request",
                  "message": "Body must be JSON."
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "`assessment_id` is not in your organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "assessment_id not in your organization"
                }
              }
            }
          },
          "500": {
            "description": "The ledger table is not present in this install.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "store_failed",
                  "message": "Could not record the event — has docs/db-ai-ledger.sql been run?"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/exposure": {
      "get": {
        "operationId": "list-exposure",
        "tags": [
          "AI governance"
        ],
        "summary": "Read exposure findings",
        "description": "AI-in-OT exposure findings previously pushed from floor scans.",
        "parameters": [
          {
            "name": "assessment_id",
            "in": "query",
            "required": false,
            "description": "Restrict to one assessment. Omit for the whole organization.",
            "schema": {
              "type": "string"
            },
            "example": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5"
          },
          {
            "name": "scan_id",
            "in": "query",
            "required": false,
            "description": "Restrict to one scan run.",
            "schema": {
              "type": "string"
            },
            "example": "scan-2026-07-19"
          }
        ],
        "responses": {
          "200": {
            "description": "Exposure findings, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "findings": [
                    {
                      "id": "7c1e4b23-0d55-4a9f-9c31-8ab0e2d47f16",
                      "job_id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                      "scan_id": "scan-2026-07-19",
                      "source": "exposure-scan",
                      "file": "hmi/scripts/assistant.py",
                      "line": 88,
                      "kind": "llm-call",
                      "provider": "openai",
                      "snippet": "client.chat.completions.create(...)",
                      "influence_level": "L2",
                      "severity": "medium",
                      "gaps": [
                        "no human approval step",
                        "no evidence citation"
                      ],
                      "status": "open",
                      "created_at": "2026-07-19T06:02:11.000Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "push-exposure",
        "tags": [
          "AI governance"
        ],
        "summary": "Push exposure findings",
        "description": "Bulk-push findings from a floor exposure scan (`scripts/exposure-scan.mjs --post`). `findings[]` is required; up to 5000 per call.",
        "requestBody": {
          "required": true,
          "description": "The scan run and its findings.",
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              },
              "example": {
                "source": "exposure-scan",
                "scan_id": "scan-2026-07-19",
                "assessment_id": "8f3b1c62-5d94-4a17-9f0e-2c6a7b41d8e5",
                "findings": [
                  {
                    "file": "hmi/scripts/assistant.py",
                    "line": 88,
                    "kind": "llm-call",
                    "provider": "openai",
                    "snippet": "client.chat.completions.create(...)",
                    "influence_level": "L2",
                    "severity": "medium",
                    "gaps": [
                      "no human approval step"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Stored.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "inserted": 1,
                  "scan_id": "scan-2026-07-19"
                }
              }
            }
          },
          "400": {
            "description": "Body was not JSON, or `findings[]` was missing.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "bad_request",
                  "message": "findings[] required."
                }
              }
            }
          },
          "401": {
            "description": "Missing, unknown or revoked API key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "unauthorized",
                  "message": "Provide a valid API key via Authorization: Bearer <key>."
                }
              }
            }
          },
          "404": {
            "description": "`assessment_id` is not in your organization.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "not_found",
                  "message": "assessment_id not in your organization"
                }
              }
            }
          },
          "500": {
            "description": "The exposure table is not present in this install.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {
                  "error": "store_failed",
                  "message": "Run docs/db-exposure.sql first."
                }
              }
            }
          }
        }
      }
    }
  }
}