@nvisy/sdk 0.25.0 → 0.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8129,7 +8129,7 @@ interface components {
8129
8129
  * UUID, a jurisdiction) is that layer's concern — it can encode it in the
8130
8130
  * name or carry it separately.
8131
8131
  *
8132
- * [`Redaction`]: crate::entity::provenance::EventKind::Redaction
8132
+ * [`Redaction`]: crate::entity::audit::AuditKind::Redaction
8133
8133
  */
8134
8134
  Attribution: {
8135
8135
  /** @description Human-readable description (e.g. `"right to erasure"`), when given. */
@@ -8138,170 +8138,90 @@ interface components {
8138
8138
  name: string;
8139
8139
  };
8140
8140
  /**
8141
- * @description Per-call payload a recognizer inspects for the [`Audio`] modality.
8142
- *
8143
- * Carries the encoded audio bytes; an optional filename aids diagnostics
8144
- * and encoding inference (the container format a decoder should expect).
8145
- * The recognizable text — a timestamped transcript — is *not* held here;
8146
- * a speech-to-text [`Enricher`] stamps it onto the call's
8147
- * [`artifacts`], keeping
8148
- * `AudioData` the codec's payload alone.
8149
- *
8150
- * [`Audio`]: super::Audio
8151
- * [`Enricher`]: crate::recognition::Enricher
8152
- * [`artifacts`]: crate::recognition::RecognizerContext::artifacts
8153
- */
8154
- AudioData: {
8155
- /** @description Original filename, when known. */
8156
- filename?: string;
8157
- };
8158
- /**
8159
- * @description Detected piece of sensitive information within some medium.
8141
+ * @description One node in an entity's audit DAG: a thing that happened, with its
8142
+ * effect on confidence and its tamper-evident links.
8160
8143
  *
8161
- * Generic over the [`Modality`] `M`, which is what makes the model
8162
- * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
8163
- * `Entity<Audio>`, and so on. The entity's location is the modality's
8164
- * [`Location`] type, `M::Location`.
8144
+ * Events are recorded on an entity's [`AuditLog`], forming the full audit
8145
+ * trail of its life: each recognizer that found it, the deduplication that
8146
+ * fused them, any score calibration, and the redaction that hid it. The
8147
+ * uniform spine (who, resulting score, when) is the same for every event; the
8148
+ * [`kind`] carries the event-specific detail *and* the explanation of why the
8149
+ * event happened.
8165
8150
  *
8166
- * # Birth and fusion
8151
+ * Each event links to its [`parents`] by their [`hash`]: a birth event (a
8152
+ * recognizer's first detection) has no parents, a normal step has one, and a
8153
+ * [fusion](crate::entity::audit::AuditLog::record_fusion) has several. Its own
8154
+ * [`hash`] folds the
8155
+ * payload together with the parents' hashes, so altering any event breaks
8156
+ * every event downstream of it: [`AuditLog::verify`] walks the DAG and
8157
+ * reports the first break.
8167
8158
  *
8168
- * A recognizer emits an entity directly, carrying a single recognition
8169
- * [`Event`] (its own finding) in the entity's [`provenance`]. When
8170
- * several recognizers find the same thing, a fusion step (in
8171
- * `elide`) combines their entities into one: the survivor's
8172
- * [`location`] and [`confidence`] are the *fused* values, and every
8173
- * contributing recognition event, plus a deduplication event, is
8174
- * retained in its provenance. The entity therefore carries its full
8175
- * audit trail with it.
8159
+ * `entity.confidence` always equals the [`confidence`] of the most recent
8160
+ * event. The confidence *flowing in* is not stored: it is the parents'
8161
+ * [`confidence`], recovered from the DAG.
8176
8162
  *
8177
- * [`Location`]: Modality::Location
8178
- * [`Event`]: crate::entity::provenance::Event
8179
- * [`provenance`]: Entity::provenance
8180
- * [`location`]: Entity::location
8181
- * [`confidence`]: Entity::confidence
8163
+ * [`AuditLog`]: crate::entity::audit::AuditLog
8164
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
8165
+ * [`AuditLog::verify`]: crate::entity::audit::AuditLog::verify
8166
+ * [`kind`]: AuditEvent::kind
8167
+ * [`parents`]: AuditEvent::parents
8168
+ * [`hash`]: AuditEvent::hash
8169
+ * [`confidence`]: AuditEvent::confidence
8182
8170
  */
8183
- AudioEntity: {
8184
- /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
8185
- confidence: components["schemas"]["Confidence"];
8186
- /**
8187
- * @description Coreference identifier, if a recognizer resolved this entity as one
8188
- * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
8189
- * same real-world thing.
8190
- */
8191
- coref?: components["schemas"]["EntityCoRef"];
8192
- /**
8193
- * Format: uuid
8194
- * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
8195
- * when the entity is assembled.
8196
- */
8197
- id: string;
8171
+ AudioAuditEvent: {
8198
8172
  /**
8199
- * @description What kind of sensitive information this is (resolved via a
8200
- * [`LabelCatalog`]).
8201
- */
8202
- label: components["schemas"]["LabelRef"];
8203
- /**
8204
- * @description The language of this entity's surrounding text, when a recognizer
8205
- * resolved one. `None` when unknown or language-agnostic.
8206
- */
8207
- language?: string;
8208
- /**
8209
- * @description Location of the entity within the medium (fused, if it came from more
8210
- * than one detection).
8173
+ * @description Confidence after this event: the entity's effective confidence once it
8174
+ * has happened.
8211
8175
  */
8212
- location: components["schemas"]["AudioLocation"];
8213
- /**
8214
- * @description Detection audit trail: every contributing detection and the fusion
8215
- * event, if any.
8216
- */
8217
- provenance: components["schemas"]["AudioProvenance"];
8176
+ confidence: components["schemas"]["Confidence"];
8218
8177
  /**
8219
- * @description Byte range of the match in the *recognized text* it was found in (the
8220
- * OCR layout text, the audio transcript, or the text payload itself) —
8221
- * the stable key back into that enrichment artifact, where the rich
8222
- * context lives (which OCR block, which speaker) that the geometric
8223
- * [`location`] cannot hold. `None` for entities not found via text
8224
- * recognition (e.g. a VLM box). Provenance, not a coordinate: redaction
8225
- * uses [`location`]; an audit uses this with the artifact.
8178
+ * @description This event's hash, over its payload and its parents' hashes. Assigned by
8179
+ * [`AuditLog`] when the event is recorded; read it through
8180
+ * [`hash`](Self::hash). Recomputing it is how the DAG is verified.
8226
8181
  *
8227
- * [`location`]: Entity::location
8228
- */
8229
- recognized_range?: components["schemas"]["Range_of_uint"];
8230
- };
8231
- /**
8232
- * @description One recognized entity plus the optional reviewer override.
8233
- *
8234
- * The bound mirrors elide's [`Entity<M>`]: serialization needs
8235
- * `M::Location` and `M::Data` (de)serializable, and JsonSchema
8236
- * derivation needs them schema-able. All four modalities elide
8237
- * ships satisfy these under the `serde` + `schema` features.
8238
- */
8239
- AudioEntityRecord: {
8240
- /** @description The elide entity, as recognition produced it. */
8241
- entity: components["schemas"]["AudioEntity"];
8242
- /**
8243
- * @description Reviewer-supplied redaction override.
8182
+ * Not publicly settable: only [`AuditLog`] assigns it, so a caller cannot
8183
+ * forge a self-consistent event outside the recording path.
8244
8184
  *
8245
- * `None` means "use the matching policy rule's decision";
8246
- * `Some(...)` overrides that rule for this specific entity
8247
- * at apply time. Reviewer overrides take precedence over
8248
- * every policy rule and inherit the authority of the
8249
- * [`Review::policy_id`] they name — the audit event's
8250
- * attribution stamps that policy so the trail names the
8251
- * authority under which the override fired.
8185
+ * [`AuditLog`]: crate::entity::audit::AuditLog
8252
8186
  */
8253
- review?: components["schemas"]["Review"];
8254
- };
8255
- /**
8256
- * @description One thing that happened to an entity, with its effect on confidence.
8257
- *
8258
- * Events are recorded in order on an entity's [`Provenance`], forming
8259
- * the full audit trail of its life: each recognizer that found it, the
8260
- * deduplication that fused them, any score calibration, and the
8261
- * redaction that hid it. The uniform spine (who, before/after score,
8262
- * when, why) is the same for every event; the [`kind`] carries the
8263
- * event-specific detail.
8264
- *
8265
- * `entity.confidence` always equals the [`after`] of the most recent
8266
- * event.
8267
- *
8268
- * [`Provenance`]: crate::entity::provenance::Provenance
8269
- * [`kind`]: Event::kind
8270
- * [`after`]: Event::after
8271
- */
8272
- AudioEvent: {
8273
- /** @description Confidence after this event. */
8274
- after: components["schemas"]["Confidence"];
8275
- /** @description When the event happened (UTC). */
8276
- at: string;
8187
+ hash: components["schemas"]["AuditHash"];
8188
+ /** @description Kind of event, with its event-specific detail and its rationale. */
8189
+ kind: components["schemas"]["AudioAuditKind"];
8277
8190
  /**
8278
- * @description Confidence before this event, if there was a prior value. `None` on
8279
- * the first (birth) event.
8191
+ * @description The events this one follows, by their hash. Empty for a birth event, one
8192
+ * entry for a normal step, several for a fusion. Assigned by [`AuditLog`]
8193
+ * when the event is recorded; read it through [`parents`](Self::parents).
8194
+ *
8195
+ * Not publicly settable: the links are the tamper-evident structure, so
8196
+ * only [`AuditLog::record`] / [`AuditLog::record_fusion`] assign them.
8197
+ *
8198
+ * [`AuditLog`]: crate::entity::audit::AuditLog
8199
+ * [`AuditLog::record`]: crate::entity::audit::AuditLog::record
8200
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
8280
8201
  */
8281
- before?: components["schemas"]["Confidence"];
8282
- /** @description Kind of event, with its event-specific detail. */
8283
- kind: components["schemas"]["AudioEventKind"];
8284
- /** @description Free-text explanation of what the event did and why. */
8285
- reason: string;
8202
+ parents: components["schemas"]["AuditHash"][];
8286
8203
  /**
8287
8204
  * @description Who produced this event: a recognizer name, a deduplication strategy,
8288
8205
  * an operator, or whatever acted.
8289
8206
  */
8290
8207
  source: string;
8208
+ /** @description When the event happened (UTC). */
8209
+ timestamp: string;
8291
8210
  };
8292
8211
  /**
8293
- * @description Kind of an [`Event`], carrying its event-specific detail.
8212
+ * @description Kind of an [`AuditEvent`], carrying its event-specific detail and the
8213
+ * rationale for why it happened.
8294
8214
  *
8295
8215
  * `#[non_exhaustive]`: new event kinds (verification, annotation, …)
8296
8216
  * can be added compatibly. The recognition kinds ([`Pattern`],
8297
8217
  * [`Model`]) carry the matched [`Location`]; the rest carry their own
8298
8218
  * data.
8299
8219
  *
8300
- * [`Pattern`]: EventKind::Pattern
8301
- * [`Model`]: EventKind::Model
8220
+ * [`Pattern`]: AuditKind::Pattern
8221
+ * [`Model`]: AuditKind::Model
8302
8222
  * [`Location`]: Modality::Location
8303
8223
  */
8304
- AudioEventKind: {
8224
+ AudioAuditKind: {
8305
8225
  /** @constant */
8306
8226
  kind: "pattern";
8307
8227
  /** @description Where the recognizer matched. */
@@ -8365,7 +8285,7 @@ interface components {
8365
8285
  * it is the keyword resolved through the modality's [`locate`] (a
8366
8286
  * pixel box for image, a time span for audio, the byte range for
8367
8287
  * text/tabular). `None` when the keyword's stream range could not be
8368
- * placed symmetric with a match the recognizer itself drops.
8288
+ * placed, symmetric with a match the recognizer itself drops.
8369
8289
  *
8370
8290
  * [`locate`]: crate::modality::TextRecognizable::locate
8371
8291
  */
@@ -8383,12 +8303,176 @@ interface components {
8383
8303
  /** @description How much the output leaks about the original. */
8384
8304
  leak_profile: components["schemas"]["LeakProfile"];
8385
8305
  /**
8386
- * @description Which selection rule chose this operator the automatic "why"
8306
+ * @description Which selection rule chose this operator: the automatic "why"
8387
8307
  * (matched a label, a tag, a predicate, or the fallback).
8388
8308
  */
8389
8309
  matched_by: components["schemas"]["RuleMatch"];
8390
8310
  /** @description Which operator (name + version) ran. */
8391
8311
  operator: components["schemas"]["OperatorId"];
8312
+ /**
8313
+ * @description BLAKE3 digest of the original text the operator hid, when the
8314
+ * redaction layer recorded it. Proves *what* was redacted without
8315
+ * storing the plaintext; `None` when the operator did not capture it.
8316
+ */
8317
+ span_hash?: components["schemas"]["AuditHash"];
8318
+ /**
8319
+ * Format: uint32
8320
+ * @description Byte length of the original text the operator hid, paired with
8321
+ * [`span_hash`](Self::Redaction::span_hash). `None` when not captured.
8322
+ */
8323
+ span_length?: number;
8324
+ };
8325
+ /**
8326
+ * @description Full audit trail of an [`Entity`]: every [`AuditEvent`] in its life, as a
8327
+ * tamper-evident DAG.
8328
+ *
8329
+ * Where Presidio keeps a shallow, optional, per-stage explanation that is
8330
+ * stripped by default, an `AuditLog` is always present and records the
8331
+ * entity's *entire* life: each recognizer that found it, the deduplication
8332
+ * that fused them, any confidence calibration, and the redaction that hid it.
8333
+ * Nothing is collapsed: every recognizer keeps its own recognition event with
8334
+ * its location and score.
8335
+ *
8336
+ * The events form a **directed acyclic graph**, not a flat list. A recognizer
8337
+ * records a birth event (no parents); each later step links to the event it
8338
+ * follows; and a [fusion](Self::record_fusion) links to *several* parents at
8339
+ * once: the heads of the trails it combines. This is the true shape of a
8340
+ * deduplicated entity: two recognizers are siblings, then a fusion joins them.
8341
+ * The events are stored in the order they were recorded, which is a
8342
+ * topological order of the DAG (a parent is always recorded before its
8343
+ * children).
8344
+ *
8345
+ * Two chains ride the DAG's edges:
8346
+ *
8347
+ * - a **confidence chain**, where each event's [`confidence`] is the entity's
8348
+ * effective score after it; the score flowing *in* is its parents'
8349
+ * confidence, so [`final_confidence`] and the full history are recoverable;
8350
+ * - a **hash chain**, where each event's [`hash`] folds its payload together
8351
+ * with its parents' hashes, so any edit, reorder, insertion, or deletion of
8352
+ * an earlier event breaks every event downstream. [`verify`] walks the DAG
8353
+ * and reports the first break.
8354
+ *
8355
+ * [`Entity`]: crate::entity::Entity
8356
+ * [`confidence`]: AuditEvent::confidence
8357
+ * [`hash`]: AuditEvent::hash
8358
+ * [`final_confidence`]: Self::final_confidence
8359
+ * [`verify`]: Self::verify
8360
+ */
8361
+ AudioAuditLog: components["schemas"]["AudioAuditEvent"][];
8362
+ /**
8363
+ * @description Per-call payload a recognizer inspects for the [`Audio`] modality.
8364
+ *
8365
+ * Carries the encoded audio bytes; an optional filename aids diagnostics
8366
+ * and encoding inference (the container format a decoder should expect).
8367
+ * The recognizable text — a timestamped transcript — is *not* held here;
8368
+ * a speech-to-text [`Enricher`] stamps it onto the call's
8369
+ * [`artifacts`], keeping
8370
+ * `AudioData` the codec's payload alone.
8371
+ *
8372
+ * [`Audio`]: super::Audio
8373
+ * [`Enricher`]: crate::recognition::Enricher
8374
+ * [`artifacts`]: crate::recognition::RecognizerContext::artifacts
8375
+ */
8376
+ AudioData: {
8377
+ /** @description Original filename, when known. */
8378
+ filename?: string;
8379
+ };
8380
+ /**
8381
+ * @description Detected piece of sensitive information within some medium.
8382
+ *
8383
+ * Generic over the [`Modality`] `M`, which is what makes the model
8384
+ * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
8385
+ * `Entity<Audio>`, and so on. The entity's location is the modality's
8386
+ * [`Location`] type, `M::Location`.
8387
+ *
8388
+ * # Birth and fusion
8389
+ *
8390
+ * A recognizer emits an entity directly, carrying a single recognition
8391
+ * [`AuditEvent`] (its own finding) in the entity's [`audit`] trail. When
8392
+ * several recognizers find the same thing, a fusion step (in
8393
+ * `elide`) combines their entities into one: the survivor's
8394
+ * [`location`] and [`confidence`] are the *fused* values, and every
8395
+ * contributing recognition event, plus a deduplication event, is
8396
+ * retained in its audit trail. The entity therefore carries its full
8397
+ * audit trail with it.
8398
+ *
8399
+ * [`Location`]: Modality::Location
8400
+ * [`AuditEvent`]: crate::entity::audit::AuditEvent
8401
+ * [`audit`]: Entity::audit
8402
+ * [`location`]: Entity::location
8403
+ * [`confidence`]: Entity::confidence
8404
+ */
8405
+ AudioEntity: {
8406
+ /**
8407
+ * @description Tamper-evident audit trail: every contributing detection, the fusion
8408
+ * event if any, and the redaction that hid it, as a hash-linked DAG.
8409
+ */
8410
+ audit: components["schemas"]["AudioAuditLog"];
8411
+ /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
8412
+ confidence: components["schemas"]["Confidence"];
8413
+ /**
8414
+ * @description Coreference identifier, if a recognizer resolved this entity as one
8415
+ * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
8416
+ * same real-world thing.
8417
+ */
8418
+ coref?: components["schemas"]["EntityCoRef"];
8419
+ /**
8420
+ * Format: uuid
8421
+ * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
8422
+ * when the entity is assembled.
8423
+ */
8424
+ id: string;
8425
+ /**
8426
+ * @description What kind of sensitive information this is (resolved via a
8427
+ * [`LabelCatalog`]).
8428
+ */
8429
+ label: components["schemas"]["LabelRef"];
8430
+ /**
8431
+ * @description The language of this entity's surrounding text, when a recognizer
8432
+ * resolved one. `None` when unknown or language-agnostic.
8433
+ */
8434
+ language?: string;
8435
+ /**
8436
+ * @description Location of the entity within the medium (fused, if it came from more
8437
+ * than one detection).
8438
+ */
8439
+ location: components["schemas"]["AudioLocation"];
8440
+ /**
8441
+ * @description Byte range of the match in the *recognized text* it was found in (the
8442
+ * OCR layout text, the audio transcript, or the text payload itself) —
8443
+ * the stable key back into that enrichment artifact, where the rich
8444
+ * context lives (which OCR block, which speaker) that the geometric
8445
+ * [`location`] cannot hold. `None` for entities not found via text
8446
+ * recognition (e.g. a VLM box). An audit key, not a coordinate: redaction
8447
+ * uses [`location`]; an audit uses this with the artifact.
8448
+ *
8449
+ * [`location`]: Entity::location
8450
+ */
8451
+ recognized_range?: components["schemas"]["Range_of_uint"];
8452
+ };
8453
+ /**
8454
+ * @description One recognized entity plus the optional reviewer override.
8455
+ *
8456
+ * The bound mirrors elide's [`Entity<M>`]: serialization needs
8457
+ * `M::Location` and `M::Data` (de)serializable, and JsonSchema
8458
+ * derivation needs them schema-able. All four modalities elide
8459
+ * ships satisfy these under the `serde` + `schema` features.
8460
+ */
8461
+ AudioEntityRecord: {
8462
+ /** @description The elide entity, as recognition produced it. */
8463
+ entity: components["schemas"]["AudioEntity"];
8464
+ /**
8465
+ * @description Reviewer-supplied redaction override.
8466
+ *
8467
+ * `None` means "use the matching policy rule's decision";
8468
+ * `Some(...)` overrides that rule for this specific entity
8469
+ * at apply time. Reviewer overrides take precedence over
8470
+ * every policy rule and inherit the authority of the
8471
+ * [`Review::policy_id`] they name — the audit event's
8472
+ * attribution stamps that policy so the trail names the
8473
+ * authority under which the override fired.
8474
+ */
8475
+ review?: components["schemas"]["Review"];
8392
8476
  };
8393
8477
  /**
8394
8478
  * @description Located, typed piece of context a recognizer may treat as in-context
@@ -8430,31 +8514,6 @@ interface components {
8430
8514
  /** @description Diarization label of the speaker, when a diarizer assigned one. */
8431
8515
  speaker_id?: string;
8432
8516
  };
8433
- /**
8434
- * @description Full audit trail of an [`Entity`]: every [`Event`] in its life, in
8435
- * order.
8436
- *
8437
- * This is the model's answer to "full provenance": where Presidio keeps
8438
- * a shallow, optional, per-stage explanation that is stripped by
8439
- * default, a `Provenance` is always present and records the entity's
8440
- * *entire* life as an ordered list of events: each recognizer that
8441
- * found it, the deduplication that fused them, any confidence
8442
- * calibration, and the redaction that hid it. Nothing is collapsed:
8443
- * every recognizer keeps its own recognition event with its location
8444
- * and score.
8445
- *
8446
- * The events form a confidence chain (each event's [`after`] is the
8447
- * next's [`before`]) so the final confidence and its full history are
8448
- * always recoverable.
8449
- *
8450
- * [`Entity`]: crate::entity::Entity
8451
- * [`after`]: Event::after
8452
- * [`before`]: Event::before
8453
- */
8454
- AudioProvenance: {
8455
- /** @description Events, in the order they happened. */
8456
- events: components["schemas"]["AudioEvent"][];
8457
- };
8458
8517
  /** @description Operator spec a `redact` audio rule carries. */
8459
8518
  AudioRedaction: {
8460
8519
  /** @constant */
@@ -8611,6 +8670,21 @@ interface components {
8611
8670
  */
8612
8671
  ocrMode: components["schemas"]["OcrMode"];
8613
8672
  };
8673
+ /**
8674
+ * @description A 32-byte BLAKE3 digest.
8675
+ *
8676
+ * The tamper-evident link in an [`AuditLog`] DAG: each [`AuditEvent`] hashes
8677
+ * its payload together with its parents' hashes, so altering any event breaks
8678
+ * every event downstream of it. Displays and (with the `serde` feature)
8679
+ * (de)serializes as lowercase hex.
8680
+ *
8681
+ * The all-zero hash is [`GENESIS`](AuditHash::GENESIS), the link a birth event
8682
+ * (one with no parents) chains from.
8683
+ *
8684
+ * [`AuditLog`]: crate::entity::audit::AuditLog
8685
+ * [`AuditEvent`]: crate::entity::audit::AuditEvent
8686
+ */
8687
+ AuditHash: string;
8614
8688
  /** @description Response returned after successful authentication (login/signup). */
8615
8689
  AuthToken: {
8616
8690
  /** @description The JWT API token for authentication. */
@@ -8690,6 +8764,24 @@ interface components {
8690
8764
  /** @description Minimum corner (top-left, conventionally). */
8691
8765
  min: components["schemas"]["Point"];
8692
8766
  };
8767
+ /**
8768
+ * @description The coarse group a [`Label`] belongs to, for organizing detected entities
8769
+ * by kind (`financial`, `health`, `identity`, …).
8770
+ *
8771
+ * A category answers "what *sort* of information is this" at a display level:
8772
+ * a consumer groups a redaction audit into sections by category. It is
8773
+ * distinct from a label's [`tags`], which are cross-cutting sensitivity
8774
+ * markers (`pii`, `phi`, `pci`) a label may carry several of; a label has at
8775
+ * most **one** category. Built-in labels ship with a category; a custom
8776
+ * [`Label`] has none unless one is set.
8777
+ *
8778
+ * The value is an open, lowercase `snake_case` identifier, so a custom label
8779
+ * can define its own category rather than being confined to the shipped set.
8780
+ *
8781
+ * [`Label`]: super::Label
8782
+ * [`tags`]: super::Label::tags
8783
+ */
8784
+ Category: string;
8693
8785
  /**
8694
8786
  * @description Text a [`TextRedaction::Clamp`] emits for out-of-range values.
8695
8787
  *
@@ -8750,7 +8842,7 @@ interface components {
8750
8842
  * Format: float
8751
8843
  * @description Confidence score in the closed range `0.0..=1.0`.
8752
8844
  *
8753
- * Carried by every provenance [`Event`] (the `before`/`after` of a
8845
+ * Carried by every provenance [`AuditEvent`] (the `before`/`after` of a
8754
8846
  * recognition, fusion, or calibration) and by the effective confidence
8755
8847
  * of an [`Entity`]. The newtype enforces the range at construction so
8756
8848
  * no downstream code has to defend against values outside `[0, 1]`.
@@ -8760,7 +8852,7 @@ interface components {
8760
8852
  * *cutoff* configured to filter scores. Compare the two with
8761
8853
  * [`ConfidenceThreshold::passes`].
8762
8854
  *
8763
- * [`Event`]: crate::entity::provenance::Event
8855
+ * [`AuditEvent`]: crate::entity::audit::AuditEvent
8764
8856
  * [`Entity`]: crate::entity::Entity
8765
8857
  */
8766
8858
  Confidence: number;
@@ -9384,6 +9476,29 @@ interface components {
9384
9476
  */
9385
9477
  serviceAccountPath: string;
9386
9478
  };
9479
+ /**
9480
+ * @description The GDPR Article 9 template config — treatment axis fused
9481
+ * with sensitive-scope axis. Carried directly by
9482
+ * [`crate::PolicyTemplate::GdprArticle9`].
9483
+ */
9484
+ GdprArticle9: {
9485
+ /**
9486
+ * @description Which sensitive-data labels to cover. Defaults to
9487
+ * [`GdprSensitiveScope::Article9`] (nine Article 9(1)
9488
+ * categories only). Pick
9489
+ * [`GdprSensitiveScope::Article9WithReidHardening`] to add
9490
+ * Recital 26 quasi-identifiers, or
9491
+ * [`GdprSensitiveScope::Article9And10`] to also cover
9492
+ * Article 10 criminal-justice data.
9493
+ * @default article9
9494
+ */
9495
+ scope: components["schemas"]["GdprSensitiveScope"];
9496
+ /**
9497
+ * @description Which operator to apply to matches. See
9498
+ * [`GdprArticle9Treatment`] for the tradeoff.
9499
+ */
9500
+ treatment: components["schemas"]["GdprArticle9Treatment"];
9501
+ };
9387
9502
  /**
9388
9503
  * @description Which operator to apply to Article 9 special-category entities.
9389
9504
  *
@@ -9398,6 +9513,31 @@ interface components {
9398
9513
  * obligation to establish and document.
9399
9514
  */
9400
9515
  GdprArticle9Treatment: "erase" | "pseudonymize";
9516
+ /**
9517
+ * @description Which sensitive-data labels the template's group covers.
9518
+ *
9519
+ * Three tiers, each strictly widening the previous one so a
9520
+ * caller upgrading through the tiers never loses coverage:
9521
+ *
9522
+ * - [`Article9`](Self::Article9) — the nine Article 9(1)
9523
+ * special categories only. The default.
9524
+ * - [`Article9WithReidHardening`](Self::Article9WithReidHardening) —
9525
+ * Article 9 plus `date_of_birth` and `postal_code`. The two
9526
+ * quasi-identifiers Recital 26 highlights as re-identification
9527
+ * vectors when combined with special-category data. Non-
9528
+ * binding guidance, but reflects supervisory-authority
9529
+ * expectations on pseudonymization robustness.
9530
+ * - [`Article9And10`](Self::Article9And10) — Article 9 + Recital
9531
+ * 26 hardening + Article 10's criminal-justice labels
9532
+ * (`criminal_record`, `criminal_charge`, `judicial_narrative`).
9533
+ * Article 10 governs "personal data relating to criminal
9534
+ * convictions and offences", processed only under authorized
9535
+ * official-authority control or specific Union/Member-State
9536
+ * law. Callers with criminal-justice adjacency (background-
9537
+ * check services, court-records handling, HR compliance) pick
9538
+ * this tier.
9539
+ */
9540
+ GdprSensitiveScope: "article9" | "article9_with_reid_hardening" | "article9_and10";
9401
9541
  /** @description Request to generate a shareable invite code for a workspace. */
9402
9542
  GenerateInviteCode: {
9403
9543
  /** @description When the invite code expires. */
@@ -9418,6 +9558,29 @@ interface components {
9418
9558
  };
9419
9559
  /** @description Operational status of a service component. */
9420
9560
  HealthStatus: "healthy" | "degraded" | "unhealthy";
9561
+ /**
9562
+ * @description Which account-identifier labels §164.514(b)(2)(i)(J) covers.
9563
+ *
9564
+ * The regulation names "account numbers" without enumerating
9565
+ * them; HHS OCR's 2012 guidance doesn't narrow it either. In
9566
+ * practice, covered entities and de-ID vendors treat bank
9567
+ * accounts, IBANs, and payment cards as the core §(J) set —
9568
+ * [`Standard`](Self::Standard). Cryptocurrency wallet addresses
9569
+ * are the newer case: they identify a specific holder's account
9570
+ * by function, and the §(R) catch-all pulls in "any other unique
9571
+ * identifying number, characteristic, or code" tied to an
9572
+ * individual, which arguably captures them. Deployments where
9573
+ * crypto addresses can appear in patient-facing artifacts pick
9574
+ * [`Extended`](Self::Extended); deployments where they can't
9575
+ * stay on `Standard`.
9576
+ *
9577
+ * The compliant posture for anything account-shaped is
9578
+ * "remove"; the split is only about how broadly this template
9579
+ * pre-declares the account label scope. A caller who wants
9580
+ * broader coverage combines this template's policy with a
9581
+ * separate PII scope on the same request.
9582
+ */
9583
+ HipaaAccountNumbers: "standard" | "extended";
9421
9584
  /**
9422
9585
  * @description Which HIPAA §164.514 de-identification method to apply.
9423
9586
  *
@@ -9443,168 +9606,111 @@ interface components {
9443
9606
  */
9444
9607
  HipaaDeidMethod: "safe_harbor" | "limited_data_set" | "expert_determination";
9445
9608
  /**
9446
- * @description Per-call payload a recognizer inspects for the [`Image`] modality.
9447
- *
9448
- * Carries the encoded bytes plus the pixel [`Dimensions`], which a
9449
- * recognizer that emits unit-square boxes needs to scale them into pixel
9450
- * coordinates. An optional filename aids diagnostics and encoding
9451
- * inference.
9452
- *
9453
- * [`Image`]: super::Image
9609
+ * @description The HIPAA §164.514 template config method axis fused with
9610
+ * account-identifier axis. Carried directly by
9611
+ * [`crate::PolicyTemplate::HipaaDeidentification`].
9454
9612
  */
9455
- ImageData: {
9456
- /** @description Pixel dimensions of the encoded image. */
9457
- dimensions: components["schemas"]["Dimensions"];
9458
- /** @description Original filename, when known. */
9459
- filename?: string;
9613
+ HipaaDeidentification: {
9614
+ /**
9615
+ * @description Which §(J) account-identifier labels to remove. Defaults
9616
+ * to [`HipaaAccountNumbers::Standard`] (bank account +
9617
+ * IBAN + payment card). Pick
9618
+ * [`HipaaAccountNumbers::Extended`] to add crypto wallet
9619
+ * addresses under the §(R) catch-all reading.
9620
+ * @default standard
9621
+ */
9622
+ accounts: components["schemas"]["HipaaAccountNumbers"];
9623
+ /**
9624
+ * @description Which §164.514 method to apply. See [`HipaaDeidMethod`]
9625
+ * for the tradeoff.
9626
+ */
9627
+ method: components["schemas"]["HipaaDeidMethod"];
9460
9628
  };
9461
9629
  /**
9462
- * @description Detected piece of sensitive information within some medium.
9630
+ * @description One node in an entity's audit DAG: a thing that happened, with its
9631
+ * effect on confidence and its tamper-evident links.
9463
9632
  *
9464
- * Generic over the [`Modality`] `M`, which is what makes the model
9465
- * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
9466
- * `Entity<Audio>`, and so on. The entity's location is the modality's
9467
- * [`Location`] type, `M::Location`.
9633
+ * Events are recorded on an entity's [`AuditLog`], forming the full audit
9634
+ * trail of its life: each recognizer that found it, the deduplication that
9635
+ * fused them, any score calibration, and the redaction that hid it. The
9636
+ * uniform spine (who, resulting score, when) is the same for every event; the
9637
+ * [`kind`] carries the event-specific detail *and* the explanation of why the
9638
+ * event happened.
9468
9639
  *
9469
- * # Birth and fusion
9640
+ * Each event links to its [`parents`] by their [`hash`]: a birth event (a
9641
+ * recognizer's first detection) has no parents, a normal step has one, and a
9642
+ * [fusion](crate::entity::audit::AuditLog::record_fusion) has several. Its own
9643
+ * [`hash`] folds the
9644
+ * payload together with the parents' hashes, so altering any event breaks
9645
+ * every event downstream of it: [`AuditLog::verify`] walks the DAG and
9646
+ * reports the first break.
9470
9647
  *
9471
- * A recognizer emits an entity directly, carrying a single recognition
9472
- * [`Event`] (its own finding) in the entity's [`provenance`]. When
9473
- * several recognizers find the same thing, a fusion step (in
9474
- * `elide`) combines their entities into one: the survivor's
9475
- * [`location`] and [`confidence`] are the *fused* values, and every
9476
- * contributing recognition event, plus a deduplication event, is
9477
- * retained in its provenance. The entity therefore carries its full
9478
- * audit trail with it.
9648
+ * `entity.confidence` always equals the [`confidence`] of the most recent
9649
+ * event. The confidence *flowing in* is not stored: it is the parents'
9650
+ * [`confidence`], recovered from the DAG.
9479
9651
  *
9480
- * [`Location`]: Modality::Location
9481
- * [`Event`]: crate::entity::provenance::Event
9482
- * [`provenance`]: Entity::provenance
9483
- * [`location`]: Entity::location
9484
- * [`confidence`]: Entity::confidence
9652
+ * [`AuditLog`]: crate::entity::audit::AuditLog
9653
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
9654
+ * [`AuditLog::verify`]: crate::entity::audit::AuditLog::verify
9655
+ * [`kind`]: AuditEvent::kind
9656
+ * [`parents`]: AuditEvent::parents
9657
+ * [`hash`]: AuditEvent::hash
9658
+ * [`confidence`]: AuditEvent::confidence
9485
9659
  */
9486
- ImageEntity: {
9487
- /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
9488
- confidence: components["schemas"]["Confidence"];
9489
- /**
9490
- * @description Coreference identifier, if a recognizer resolved this entity as one
9491
- * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
9492
- * same real-world thing.
9493
- */
9494
- coref?: components["schemas"]["EntityCoRef"];
9495
- /**
9496
- * Format: uuid
9497
- * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
9498
- * when the entity is assembled.
9499
- */
9500
- id: string;
9660
+ ImageAuditEvent: {
9501
9661
  /**
9502
- * @description What kind of sensitive information this is (resolved via a
9503
- * [`LabelCatalog`]).
9504
- */
9505
- label: components["schemas"]["LabelRef"];
9506
- /**
9507
- * @description The language of this entity's surrounding text, when a recognizer
9508
- * resolved one. `None` when unknown or language-agnostic.
9509
- */
9510
- language?: string;
9511
- /**
9512
- * @description Location of the entity within the medium (fused, if it came from more
9513
- * than one detection).
9662
+ * @description Confidence after this event: the entity's effective confidence once it
9663
+ * has happened.
9514
9664
  */
9515
- location: components["schemas"]["ImageLocation"];
9516
- /**
9517
- * @description Detection audit trail: every contributing detection and the fusion
9518
- * event, if any.
9519
- */
9520
- provenance: components["schemas"]["ImageProvenance"];
9665
+ confidence: components["schemas"]["Confidence"];
9521
9666
  /**
9522
- * @description Byte range of the match in the *recognized text* it was found in (the
9523
- * OCR layout text, the audio transcript, or the text payload itself) —
9524
- * the stable key back into that enrichment artifact, where the rich
9525
- * context lives (which OCR block, which speaker) that the geometric
9526
- * [`location`] cannot hold. `None` for entities not found via text
9527
- * recognition (e.g. a VLM box). Provenance, not a coordinate: redaction
9528
- * uses [`location`]; an audit uses this with the artifact.
9667
+ * @description This event's hash, over its payload and its parents' hashes. Assigned by
9668
+ * [`AuditLog`] when the event is recorded; read it through
9669
+ * [`hash`](Self::hash). Recomputing it is how the DAG is verified.
9529
9670
  *
9530
- * [`location`]: Entity::location
9531
- */
9532
- recognized_range?: components["schemas"]["Range_of_uint"];
9533
- };
9534
- /**
9535
- * @description One recognized entity plus the optional reviewer override.
9536
- *
9537
- * The bound mirrors elide's [`Entity<M>`]: serialization needs
9538
- * `M::Location` and `M::Data` (de)serializable, and JsonSchema
9539
- * derivation needs them schema-able. All four modalities elide
9540
- * ships satisfy these under the `serde` + `schema` features.
9541
- */
9542
- ImageEntityRecord: {
9543
- /** @description The elide entity, as recognition produced it. */
9544
- entity: components["schemas"]["ImageEntity"];
9545
- /**
9546
- * @description Reviewer-supplied redaction override.
9671
+ * Not publicly settable: only [`AuditLog`] assigns it, so a caller cannot
9672
+ * forge a self-consistent event outside the recording path.
9547
9673
  *
9548
- * `None` means "use the matching policy rule's decision";
9549
- * `Some(...)` overrides that rule for this specific entity
9550
- * at apply time. Reviewer overrides take precedence over
9551
- * every policy rule and inherit the authority of the
9552
- * [`Review::policy_id`] they name — the audit event's
9553
- * attribution stamps that policy so the trail names the
9554
- * authority under which the override fired.
9674
+ * [`AuditLog`]: crate::entity::audit::AuditLog
9555
9675
  */
9556
- review?: components["schemas"]["Review"];
9557
- };
9558
- /**
9559
- * @description One thing that happened to an entity, with its effect on confidence.
9560
- *
9561
- * Events are recorded in order on an entity's [`Provenance`], forming
9562
- * the full audit trail of its life: each recognizer that found it, the
9563
- * deduplication that fused them, any score calibration, and the
9564
- * redaction that hid it. The uniform spine (who, before/after score,
9565
- * when, why) is the same for every event; the [`kind`] carries the
9566
- * event-specific detail.
9567
- *
9568
- * `entity.confidence` always equals the [`after`] of the most recent
9569
- * event.
9570
- *
9571
- * [`Provenance`]: crate::entity::provenance::Provenance
9572
- * [`kind`]: Event::kind
9573
- * [`after`]: Event::after
9574
- */
9575
- ImageEvent: {
9576
- /** @description Confidence after this event. */
9577
- after: components["schemas"]["Confidence"];
9578
- /** @description When the event happened (UTC). */
9579
- at: string;
9676
+ hash: components["schemas"]["AuditHash"];
9677
+ /** @description Kind of event, with its event-specific detail and its rationale. */
9678
+ kind: components["schemas"]["ImageAuditKind"];
9580
9679
  /**
9581
- * @description Confidence before this event, if there was a prior value. `None` on
9582
- * the first (birth) event.
9680
+ * @description The events this one follows, by their hash. Empty for a birth event, one
9681
+ * entry for a normal step, several for a fusion. Assigned by [`AuditLog`]
9682
+ * when the event is recorded; read it through [`parents`](Self::parents).
9683
+ *
9684
+ * Not publicly settable: the links are the tamper-evident structure, so
9685
+ * only [`AuditLog::record`] / [`AuditLog::record_fusion`] assign them.
9686
+ *
9687
+ * [`AuditLog`]: crate::entity::audit::AuditLog
9688
+ * [`AuditLog::record`]: crate::entity::audit::AuditLog::record
9689
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
9583
9690
  */
9584
- before?: components["schemas"]["Confidence"];
9585
- /** @description Kind of event, with its event-specific detail. */
9586
- kind: components["schemas"]["ImageEventKind"];
9587
- /** @description Free-text explanation of what the event did and why. */
9588
- reason: string;
9691
+ parents: components["schemas"]["AuditHash"][];
9589
9692
  /**
9590
9693
  * @description Who produced this event: a recognizer name, a deduplication strategy,
9591
9694
  * an operator, or whatever acted.
9592
9695
  */
9593
9696
  source: string;
9697
+ /** @description When the event happened (UTC). */
9698
+ timestamp: string;
9594
9699
  };
9595
9700
  /**
9596
- * @description Kind of an [`Event`], carrying its event-specific detail.
9701
+ * @description Kind of an [`AuditEvent`], carrying its event-specific detail and the
9702
+ * rationale for why it happened.
9597
9703
  *
9598
9704
  * `#[non_exhaustive]`: new event kinds (verification, annotation, …)
9599
9705
  * can be added compatibly. The recognition kinds ([`Pattern`],
9600
9706
  * [`Model`]) carry the matched [`Location`]; the rest carry their own
9601
9707
  * data.
9602
9708
  *
9603
- * [`Pattern`]: EventKind::Pattern
9604
- * [`Model`]: EventKind::Model
9709
+ * [`Pattern`]: AuditKind::Pattern
9710
+ * [`Model`]: AuditKind::Model
9605
9711
  * [`Location`]: Modality::Location
9606
9712
  */
9607
- ImageEventKind: {
9713
+ ImageAuditKind: {
9608
9714
  /** @constant */
9609
9715
  kind: "pattern";
9610
9716
  /** @description Where the recognizer matched. */
@@ -9668,7 +9774,7 @@ interface components {
9668
9774
  * it is the keyword resolved through the modality's [`locate`] (a
9669
9775
  * pixel box for image, a time span for audio, the byte range for
9670
9776
  * text/tabular). `None` when the keyword's stream range could not be
9671
- * placed symmetric with a match the recognizer itself drops.
9777
+ * placed, symmetric with a match the recognizer itself drops.
9672
9778
  *
9673
9779
  * [`locate`]: crate::modality::TextRecognizable::locate
9674
9780
  */
@@ -9686,12 +9792,174 @@ interface components {
9686
9792
  /** @description How much the output leaks about the original. */
9687
9793
  leak_profile: components["schemas"]["LeakProfile"];
9688
9794
  /**
9689
- * @description Which selection rule chose this operator the automatic "why"
9795
+ * @description Which selection rule chose this operator: the automatic "why"
9690
9796
  * (matched a label, a tag, a predicate, or the fallback).
9691
9797
  */
9692
9798
  matched_by: components["schemas"]["RuleMatch"];
9693
9799
  /** @description Which operator (name + version) ran. */
9694
9800
  operator: components["schemas"]["OperatorId"];
9801
+ /**
9802
+ * @description BLAKE3 digest of the original text the operator hid, when the
9803
+ * redaction layer recorded it. Proves *what* was redacted without
9804
+ * storing the plaintext; `None` when the operator did not capture it.
9805
+ */
9806
+ span_hash?: components["schemas"]["AuditHash"];
9807
+ /**
9808
+ * Format: uint32
9809
+ * @description Byte length of the original text the operator hid, paired with
9810
+ * [`span_hash`](Self::Redaction::span_hash). `None` when not captured.
9811
+ */
9812
+ span_length?: number;
9813
+ };
9814
+ /**
9815
+ * @description Full audit trail of an [`Entity`]: every [`AuditEvent`] in its life, as a
9816
+ * tamper-evident DAG.
9817
+ *
9818
+ * Where Presidio keeps a shallow, optional, per-stage explanation that is
9819
+ * stripped by default, an `AuditLog` is always present and records the
9820
+ * entity's *entire* life: each recognizer that found it, the deduplication
9821
+ * that fused them, any confidence calibration, and the redaction that hid it.
9822
+ * Nothing is collapsed: every recognizer keeps its own recognition event with
9823
+ * its location and score.
9824
+ *
9825
+ * The events form a **directed acyclic graph**, not a flat list. A recognizer
9826
+ * records a birth event (no parents); each later step links to the event it
9827
+ * follows; and a [fusion](Self::record_fusion) links to *several* parents at
9828
+ * once: the heads of the trails it combines. This is the true shape of a
9829
+ * deduplicated entity: two recognizers are siblings, then a fusion joins them.
9830
+ * The events are stored in the order they were recorded, which is a
9831
+ * topological order of the DAG (a parent is always recorded before its
9832
+ * children).
9833
+ *
9834
+ * Two chains ride the DAG's edges:
9835
+ *
9836
+ * - a **confidence chain**, where each event's [`confidence`] is the entity's
9837
+ * effective score after it; the score flowing *in* is its parents'
9838
+ * confidence, so [`final_confidence`] and the full history are recoverable;
9839
+ * - a **hash chain**, where each event's [`hash`] folds its payload together
9840
+ * with its parents' hashes, so any edit, reorder, insertion, or deletion of
9841
+ * an earlier event breaks every event downstream. [`verify`] walks the DAG
9842
+ * and reports the first break.
9843
+ *
9844
+ * [`Entity`]: crate::entity::Entity
9845
+ * [`confidence`]: AuditEvent::confidence
9846
+ * [`hash`]: AuditEvent::hash
9847
+ * [`final_confidence`]: Self::final_confidence
9848
+ * [`verify`]: Self::verify
9849
+ */
9850
+ ImageAuditLog: components["schemas"]["ImageAuditEvent"][];
9851
+ /**
9852
+ * @description Per-call payload a recognizer inspects for the [`Image`] modality.
9853
+ *
9854
+ * Carries the encoded bytes plus the pixel [`Dimensions`], which a
9855
+ * recognizer that emits unit-square boxes needs to scale them into pixel
9856
+ * coordinates. An optional filename aids diagnostics and encoding
9857
+ * inference.
9858
+ *
9859
+ * [`Image`]: super::Image
9860
+ */
9861
+ ImageData: {
9862
+ /** @description Pixel dimensions of the encoded image. */
9863
+ dimensions: components["schemas"]["Dimensions"];
9864
+ /** @description Original filename, when known. */
9865
+ filename?: string;
9866
+ };
9867
+ /**
9868
+ * @description Detected piece of sensitive information within some medium.
9869
+ *
9870
+ * Generic over the [`Modality`] `M`, which is what makes the model
9871
+ * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
9872
+ * `Entity<Audio>`, and so on. The entity's location is the modality's
9873
+ * [`Location`] type, `M::Location`.
9874
+ *
9875
+ * # Birth and fusion
9876
+ *
9877
+ * A recognizer emits an entity directly, carrying a single recognition
9878
+ * [`AuditEvent`] (its own finding) in the entity's [`audit`] trail. When
9879
+ * several recognizers find the same thing, a fusion step (in
9880
+ * `elide`) combines their entities into one: the survivor's
9881
+ * [`location`] and [`confidence`] are the *fused* values, and every
9882
+ * contributing recognition event, plus a deduplication event, is
9883
+ * retained in its audit trail. The entity therefore carries its full
9884
+ * audit trail with it.
9885
+ *
9886
+ * [`Location`]: Modality::Location
9887
+ * [`AuditEvent`]: crate::entity::audit::AuditEvent
9888
+ * [`audit`]: Entity::audit
9889
+ * [`location`]: Entity::location
9890
+ * [`confidence`]: Entity::confidence
9891
+ */
9892
+ ImageEntity: {
9893
+ /**
9894
+ * @description Tamper-evident audit trail: every contributing detection, the fusion
9895
+ * event if any, and the redaction that hid it, as a hash-linked DAG.
9896
+ */
9897
+ audit: components["schemas"]["ImageAuditLog"];
9898
+ /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
9899
+ confidence: components["schemas"]["Confidence"];
9900
+ /**
9901
+ * @description Coreference identifier, if a recognizer resolved this entity as one
9902
+ * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
9903
+ * same real-world thing.
9904
+ */
9905
+ coref?: components["schemas"]["EntityCoRef"];
9906
+ /**
9907
+ * Format: uuid
9908
+ * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
9909
+ * when the entity is assembled.
9910
+ */
9911
+ id: string;
9912
+ /**
9913
+ * @description What kind of sensitive information this is (resolved via a
9914
+ * [`LabelCatalog`]).
9915
+ */
9916
+ label: components["schemas"]["LabelRef"];
9917
+ /**
9918
+ * @description The language of this entity's surrounding text, when a recognizer
9919
+ * resolved one. `None` when unknown or language-agnostic.
9920
+ */
9921
+ language?: string;
9922
+ /**
9923
+ * @description Location of the entity within the medium (fused, if it came from more
9924
+ * than one detection).
9925
+ */
9926
+ location: components["schemas"]["ImageLocation"];
9927
+ /**
9928
+ * @description Byte range of the match in the *recognized text* it was found in (the
9929
+ * OCR layout text, the audio transcript, or the text payload itself) —
9930
+ * the stable key back into that enrichment artifact, where the rich
9931
+ * context lives (which OCR block, which speaker) that the geometric
9932
+ * [`location`] cannot hold. `None` for entities not found via text
9933
+ * recognition (e.g. a VLM box). An audit key, not a coordinate: redaction
9934
+ * uses [`location`]; an audit uses this with the artifact.
9935
+ *
9936
+ * [`location`]: Entity::location
9937
+ */
9938
+ recognized_range?: components["schemas"]["Range_of_uint"];
9939
+ };
9940
+ /**
9941
+ * @description One recognized entity plus the optional reviewer override.
9942
+ *
9943
+ * The bound mirrors elide's [`Entity<M>`]: serialization needs
9944
+ * `M::Location` and `M::Data` (de)serializable, and JsonSchema
9945
+ * derivation needs them schema-able. All four modalities elide
9946
+ * ships satisfy these under the `serde` + `schema` features.
9947
+ */
9948
+ ImageEntityRecord: {
9949
+ /** @description The elide entity, as recognition produced it. */
9950
+ entity: components["schemas"]["ImageEntity"];
9951
+ /**
9952
+ * @description Reviewer-supplied redaction override.
9953
+ *
9954
+ * `None` means "use the matching policy rule's decision";
9955
+ * `Some(...)` overrides that rule for this specific entity
9956
+ * at apply time. Reviewer overrides take precedence over
9957
+ * every policy rule and inherit the authority of the
9958
+ * [`Review::policy_id`] they name — the audit event's
9959
+ * attribution stamps that policy so the trail names the
9960
+ * authority under which the override fired.
9961
+ */
9962
+ review?: components["schemas"]["Review"];
9695
9963
  };
9696
9964
  /**
9697
9965
  * @description Located, typed piece of context a recognizer may treat as in-context
@@ -9738,31 +10006,6 @@ interface components {
9738
10006
  */
9739
10007
  polygon?: components["schemas"]["Polygon"];
9740
10008
  };
9741
- /**
9742
- * @description Full audit trail of an [`Entity`]: every [`Event`] in its life, in
9743
- * order.
9744
- *
9745
- * This is the model's answer to "full provenance": where Presidio keeps
9746
- * a shallow, optional, per-stage explanation that is stripped by
9747
- * default, a `Provenance` is always present and records the entity's
9748
- * *entire* life as an ordered list of events: each recognizer that
9749
- * found it, the deduplication that fused them, any confidence
9750
- * calibration, and the redaction that hid it. Nothing is collapsed:
9751
- * every recognizer keeps its own recognition event with its location
9752
- * and score.
9753
- *
9754
- * The events form a confidence chain (each event's [`after`] is the
9755
- * next's [`before`]) so the final confidence and its full history are
9756
- * always recoverable.
9757
- *
9758
- * [`Entity`]: crate::entity::Entity
9759
- * [`after`]: Event::after
9760
- * [`before`]: Event::before
9761
- */
9762
- ImageProvenance: {
9763
- /** @description Events, in the order they happened. */
9764
- events: components["schemas"]["ImageEvent"][];
9765
- };
9766
10009
  /** @description Operator spec a `redact` image rule carries. */
9767
10010
  ImageRedaction: {
9768
10011
  /** @constant */
@@ -9947,7 +10190,7 @@ interface components {
9947
10190
  InviteStatus: "pending" | "accepted" | "declined" | "canceled" | "expired" | "revoked";
9948
10191
  /**
9949
10192
  * @description Kind of sensitive information: a stable [`id`], per-language
9950
- * [`LabelLocale`]s, and zero or more tags.
10193
+ * [`LabelLocale`]s, an optional [`category`], and zero or more tags.
9951
10194
  *
9952
10195
  * # Identity
9953
10196
  *
@@ -9965,18 +10208,25 @@ interface components {
9965
10208
  * text — NER and LLM read the analysis language's name and description to
9966
10209
  * prompt the model, keyed by the stable id.
9967
10210
  *
9968
- * # Tags
10211
+ * # Category and tags
10212
+ *
10213
+ * [`category`] is the single coarse group a label belongs to (`financial`,
10214
+ * `health`, `identity`, …), for organizing detected entities by kind. Built-in
10215
+ * labels ship with one; a custom label has none unless set.
9969
10216
  *
9970
- * [`tags`] is a free-form list of short identifiers policy selectors can
9971
- * match against. Built-in labels carry category tags (`personal_identity`,
9972
- * `contact_info`, `financial`, ) plus cross-cutting tags where applicable
9973
- * (`pii`, `phi`, `pci`). Custom labels can ship with zero tags.
10217
+ * [`tags`] is a free-form list of *cross-cutting* markers a policy selector
10218
+ * matches against sensitivity flags a label may carry several of (`pii`,
10219
+ * `phi`, `pci`, `sad`, `secret`). Distinct from the category: a label has at
10220
+ * most one category but any number of tags. Custom labels can ship with zero
10221
+ * of either.
9974
10222
  *
9975
10223
  * [`id`]: Label::id
9976
10224
  * [`localization`]: Label::localization
10225
+ * [`category`]: Label::category
9977
10226
  * [`tags`]: Label::tags
9978
10227
  */
9979
10228
  Label: {
10229
+ category?: components["schemas"]["Category"];
9980
10230
  id: string;
9981
10231
  localizations: components["schemas"]["LocalizedText"];
9982
10232
  tags: string[];
@@ -11032,7 +11282,7 @@ interface components {
11032
11282
  * [`Attribution::name`] so reviewers can find this policy
11033
11283
  * from any redaction it drove.
11034
11284
  *
11035
- * [`Attribution::name`]: elide_core::entity::provenance::Attribution::name
11285
+ * [`Attribution::name`]: elide_core::entity::audit::Attribution::name
11036
11286
  */
11037
11287
  id: string;
11038
11288
  /**
@@ -11080,7 +11330,7 @@ interface components {
11080
11330
  * reviewers can trace which rule fired. Every attachment a
11081
11331
  * [`RuleDispatch::Table`] expands into shares this UUID.
11082
11332
  *
11083
- * [`Attribution::description`]: elide_core::entity::provenance::Attribution::description
11333
+ * [`Attribution::description`]: elide_core::entity::audit::Attribution::description
11084
11334
  */
11085
11335
  id: string;
11086
11336
  /** @description Human-readable name. Display-only. */
@@ -11172,23 +11422,13 @@ interface components {
11172
11422
  * operator options,
11173
11423
  * `{"kind": "pci_dss_pan", "render": "hmac_sha256"}`.
11174
11424
  */
11175
- PolicyTemplate: {
11425
+ PolicyTemplate: ({
11176
11426
  /** @constant */
11177
11427
  kind: "hipaa_deidentification";
11178
- /**
11179
- * @description Which §164.514 method to apply. See [`HipaaDeidMethod`]
11180
- * for the tradeoff.
11181
- */
11182
- method: components["schemas"]["HipaaDeidMethod"];
11183
- } | {
11428
+ } & components["schemas"]["HipaaDeidentification"]) | ({
11184
11429
  /** @constant */
11185
11430
  kind: "gdpr_article9";
11186
- /**
11187
- * @description Which operator to apply to Article 9 matches. See
11188
- * [`GdprArticle9Treatment`] for the tradeoff.
11189
- */
11190
- treatment: components["schemas"]["GdprArticle9Treatment"];
11191
- } | {
11431
+ } & components["schemas"]["GdprArticle9"]) | {
11192
11432
  /** @constant */
11193
11433
  kind: "pci_dss";
11194
11434
  /**
@@ -11199,6 +11439,9 @@ interface components {
11199
11439
  } | {
11200
11440
  /** @constant */
11201
11441
  kind: "ccpa";
11442
+ } | {
11443
+ /** @constant */
11444
+ kind: "soc2_secrets";
11202
11445
  };
11203
11446
  /**
11204
11447
  * @description Closed polygon, given by its ordered vertices.
@@ -11439,7 +11682,7 @@ interface components {
11439
11682
  * closure into provenance, so [`Predicate`] records only that a predicate
11440
11683
  * matched, not which one.
11441
11684
  *
11442
- * [`Redaction`]: crate::entity::provenance::EventKind::Redaction
11685
+ * [`Redaction`]: crate::entity::audit::AuditKind::Redaction
11443
11686
  * [`Predicate`]: RuleMatch::Predicate
11444
11687
  */
11445
11688
  RuleMatch: {
@@ -11781,152 +12024,90 @@ interface components {
11781
12024
  reportId?: string;
11782
12025
  };
11783
12026
  /**
11784
- * @description Detected piece of sensitive information within some medium.
12027
+ * @description One node in an entity's audit DAG: a thing that happened, with its
12028
+ * effect on confidence and its tamper-evident links.
11785
12029
  *
11786
- * Generic over the [`Modality`] `M`, which is what makes the model
11787
- * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
11788
- * `Entity<Audio>`, and so on. The entity's location is the modality's
11789
- * [`Location`] type, `M::Location`.
12030
+ * Events are recorded on an entity's [`AuditLog`], forming the full audit
12031
+ * trail of its life: each recognizer that found it, the deduplication that
12032
+ * fused them, any score calibration, and the redaction that hid it. The
12033
+ * uniform spine (who, resulting score, when) is the same for every event; the
12034
+ * [`kind`] carries the event-specific detail *and* the explanation of why the
12035
+ * event happened.
11790
12036
  *
11791
- * # Birth and fusion
12037
+ * Each event links to its [`parents`] by their [`hash`]: a birth event (a
12038
+ * recognizer's first detection) has no parents, a normal step has one, and a
12039
+ * [fusion](crate::entity::audit::AuditLog::record_fusion) has several. Its own
12040
+ * [`hash`] folds the
12041
+ * payload together with the parents' hashes, so altering any event breaks
12042
+ * every event downstream of it: [`AuditLog::verify`] walks the DAG and
12043
+ * reports the first break.
11792
12044
  *
11793
- * A recognizer emits an entity directly, carrying a single recognition
11794
- * [`Event`] (its own finding) in the entity's [`provenance`]. When
11795
- * several recognizers find the same thing, a fusion step (in
11796
- * `elide`) combines their entities into one: the survivor's
11797
- * [`location`] and [`confidence`] are the *fused* values, and every
11798
- * contributing recognition event, plus a deduplication event, is
11799
- * retained in its provenance. The entity therefore carries its full
11800
- * audit trail with it.
12045
+ * `entity.confidence` always equals the [`confidence`] of the most recent
12046
+ * event. The confidence *flowing in* is not stored: it is the parents'
12047
+ * [`confidence`], recovered from the DAG.
11801
12048
  *
11802
- * [`Location`]: Modality::Location
11803
- * [`Event`]: crate::entity::provenance::Event
11804
- * [`provenance`]: Entity::provenance
11805
- * [`location`]: Entity::location
11806
- * [`confidence`]: Entity::confidence
12049
+ * [`AuditLog`]: crate::entity::audit::AuditLog
12050
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
12051
+ * [`AuditLog::verify`]: crate::entity::audit::AuditLog::verify
12052
+ * [`kind`]: AuditEvent::kind
12053
+ * [`parents`]: AuditEvent::parents
12054
+ * [`hash`]: AuditEvent::hash
12055
+ * [`confidence`]: AuditEvent::confidence
11807
12056
  */
11808
- TabularEntity: {
11809
- /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
11810
- confidence: components["schemas"]["Confidence"];
11811
- /**
11812
- * @description Coreference identifier, if a recognizer resolved this entity as one
11813
- * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
11814
- * same real-world thing.
11815
- */
11816
- coref?: components["schemas"]["EntityCoRef"];
12057
+ TabularAuditEvent: {
11817
12058
  /**
11818
- * Format: uuid
11819
- * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
11820
- * when the entity is assembled.
11821
- */
11822
- id: string;
11823
- /**
11824
- * @description What kind of sensitive information this is (resolved via a
11825
- * [`LabelCatalog`]).
11826
- */
11827
- label: components["schemas"]["LabelRef"];
11828
- /**
11829
- * @description The language of this entity's surrounding text, when a recognizer
11830
- * resolved one. `None` when unknown or language-agnostic.
12059
+ * @description Confidence after this event: the entity's effective confidence once it
12060
+ * has happened.
11831
12061
  */
11832
- language?: string;
11833
- /**
11834
- * @description Location of the entity within the medium (fused, if it came from more
11835
- * than one detection).
11836
- */
11837
- location: components["schemas"]["TabularLocation"];
11838
- /**
11839
- * @description Detection audit trail: every contributing detection and the fusion
11840
- * event, if any.
11841
- */
11842
- provenance: components["schemas"]["TabularProvenance"];
12062
+ confidence: components["schemas"]["Confidence"];
11843
12063
  /**
11844
- * @description Byte range of the match in the *recognized text* it was found in (the
11845
- * OCR layout text, the audio transcript, or the text payload itself) —
11846
- * the stable key back into that enrichment artifact, where the rich
11847
- * context lives (which OCR block, which speaker) that the geometric
11848
- * [`location`] cannot hold. `None` for entities not found via text
11849
- * recognition (e.g. a VLM box). Provenance, not a coordinate: redaction
11850
- * uses [`location`]; an audit uses this with the artifact.
12064
+ * @description This event's hash, over its payload and its parents' hashes. Assigned by
12065
+ * [`AuditLog`] when the event is recorded; read it through
12066
+ * [`hash`](Self::hash). Recomputing it is how the DAG is verified.
11851
12067
  *
11852
- * [`location`]: Entity::location
11853
- */
11854
- recognized_range?: components["schemas"]["Range_of_uint"];
11855
- };
11856
- /**
11857
- * @description One recognized entity plus the optional reviewer override.
11858
- *
11859
- * The bound mirrors elide's [`Entity<M>`]: serialization needs
11860
- * `M::Location` and `M::Data` (de)serializable, and JsonSchema
11861
- * derivation needs them schema-able. All four modalities elide
11862
- * ships satisfy these under the `serde` + `schema` features.
11863
- */
11864
- TabularEntityRecord: {
11865
- /** @description The elide entity, as recognition produced it. */
11866
- entity: components["schemas"]["TabularEntity"];
11867
- /**
11868
- * @description Reviewer-supplied redaction override.
12068
+ * Not publicly settable: only [`AuditLog`] assigns it, so a caller cannot
12069
+ * forge a self-consistent event outside the recording path.
11869
12070
  *
11870
- * `None` means "use the matching policy rule's decision";
11871
- * `Some(...)` overrides that rule for this specific entity
11872
- * at apply time. Reviewer overrides take precedence over
11873
- * every policy rule and inherit the authority of the
11874
- * [`Review::policy_id`] they name — the audit event's
11875
- * attribution stamps that policy so the trail names the
11876
- * authority under which the override fired.
12071
+ * [`AuditLog`]: crate::entity::audit::AuditLog
11877
12072
  */
11878
- review?: components["schemas"]["Review"];
11879
- };
11880
- /**
11881
- * @description One thing that happened to an entity, with its effect on confidence.
11882
- *
11883
- * Events are recorded in order on an entity's [`Provenance`], forming
11884
- * the full audit trail of its life: each recognizer that found it, the
11885
- * deduplication that fused them, any score calibration, and the
11886
- * redaction that hid it. The uniform spine (who, before/after score,
11887
- * when, why) is the same for every event; the [`kind`] carries the
11888
- * event-specific detail.
11889
- *
11890
- * `entity.confidence` always equals the [`after`] of the most recent
11891
- * event.
11892
- *
11893
- * [`Provenance`]: crate::entity::provenance::Provenance
11894
- * [`kind`]: Event::kind
11895
- * [`after`]: Event::after
11896
- */
11897
- TabularEvent: {
11898
- /** @description Confidence after this event. */
11899
- after: components["schemas"]["Confidence"];
11900
- /** @description When the event happened (UTC). */
11901
- at: string;
12073
+ hash: components["schemas"]["AuditHash"];
12074
+ /** @description Kind of event, with its event-specific detail and its rationale. */
12075
+ kind: components["schemas"]["TabularAuditKind"];
11902
12076
  /**
11903
- * @description Confidence before this event, if there was a prior value. `None` on
11904
- * the first (birth) event.
12077
+ * @description The events this one follows, by their hash. Empty for a birth event, one
12078
+ * entry for a normal step, several for a fusion. Assigned by [`AuditLog`]
12079
+ * when the event is recorded; read it through [`parents`](Self::parents).
12080
+ *
12081
+ * Not publicly settable: the links are the tamper-evident structure, so
12082
+ * only [`AuditLog::record`] / [`AuditLog::record_fusion`] assign them.
12083
+ *
12084
+ * [`AuditLog`]: crate::entity::audit::AuditLog
12085
+ * [`AuditLog::record`]: crate::entity::audit::AuditLog::record
12086
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
11905
12087
  */
11906
- before?: components["schemas"]["Confidence"];
11907
- /** @description Kind of event, with its event-specific detail. */
11908
- kind: components["schemas"]["TabularEventKind"];
11909
- /** @description Free-text explanation of what the event did and why. */
11910
- reason: string;
12088
+ parents: components["schemas"]["AuditHash"][];
11911
12089
  /**
11912
12090
  * @description Who produced this event: a recognizer name, a deduplication strategy,
11913
12091
  * an operator, or whatever acted.
11914
12092
  */
11915
12093
  source: string;
12094
+ /** @description When the event happened (UTC). */
12095
+ timestamp: string;
11916
12096
  };
11917
12097
  /**
11918
- * @description Kind of an [`Event`], carrying its event-specific detail.
12098
+ * @description Kind of an [`AuditEvent`], carrying its event-specific detail and the
12099
+ * rationale for why it happened.
11919
12100
  *
11920
12101
  * `#[non_exhaustive]`: new event kinds (verification, annotation, …)
11921
12102
  * can be added compatibly. The recognition kinds ([`Pattern`],
11922
12103
  * [`Model`]) carry the matched [`Location`]; the rest carry their own
11923
12104
  * data.
11924
12105
  *
11925
- * [`Pattern`]: EventKind::Pattern
11926
- * [`Model`]: EventKind::Model
12106
+ * [`Pattern`]: AuditKind::Pattern
12107
+ * [`Model`]: AuditKind::Model
11927
12108
  * [`Location`]: Modality::Location
11928
12109
  */
11929
- TabularEventKind: {
12110
+ TabularAuditKind: {
11930
12111
  /** @constant */
11931
12112
  kind: "pattern";
11932
12113
  /** @description Where the recognizer matched. */
@@ -11990,7 +12171,7 @@ interface components {
11990
12171
  * it is the keyword resolved through the modality's [`locate`] (a
11991
12172
  * pixel box for image, a time span for audio, the byte range for
11992
12173
  * text/tabular). `None` when the keyword's stream range could not be
11993
- * placed symmetric with a match the recognizer itself drops.
12174
+ * placed, symmetric with a match the recognizer itself drops.
11994
12175
  *
11995
12176
  * [`locate`]: crate::modality::TextRecognizable::locate
11996
12177
  */
@@ -12008,12 +12189,158 @@ interface components {
12008
12189
  /** @description How much the output leaks about the original. */
12009
12190
  leak_profile: components["schemas"]["LeakProfile"];
12010
12191
  /**
12011
- * @description Which selection rule chose this operator the automatic "why"
12192
+ * @description Which selection rule chose this operator: the automatic "why"
12012
12193
  * (matched a label, a tag, a predicate, or the fallback).
12013
12194
  */
12014
12195
  matched_by: components["schemas"]["RuleMatch"];
12015
12196
  /** @description Which operator (name + version) ran. */
12016
12197
  operator: components["schemas"]["OperatorId"];
12198
+ /**
12199
+ * @description BLAKE3 digest of the original text the operator hid, when the
12200
+ * redaction layer recorded it. Proves *what* was redacted without
12201
+ * storing the plaintext; `None` when the operator did not capture it.
12202
+ */
12203
+ span_hash?: components["schemas"]["AuditHash"];
12204
+ /**
12205
+ * Format: uint32
12206
+ * @description Byte length of the original text the operator hid, paired with
12207
+ * [`span_hash`](Self::Redaction::span_hash). `None` when not captured.
12208
+ */
12209
+ span_length?: number;
12210
+ };
12211
+ /**
12212
+ * @description Full audit trail of an [`Entity`]: every [`AuditEvent`] in its life, as a
12213
+ * tamper-evident DAG.
12214
+ *
12215
+ * Where Presidio keeps a shallow, optional, per-stage explanation that is
12216
+ * stripped by default, an `AuditLog` is always present and records the
12217
+ * entity's *entire* life: each recognizer that found it, the deduplication
12218
+ * that fused them, any confidence calibration, and the redaction that hid it.
12219
+ * Nothing is collapsed: every recognizer keeps its own recognition event with
12220
+ * its location and score.
12221
+ *
12222
+ * The events form a **directed acyclic graph**, not a flat list. A recognizer
12223
+ * records a birth event (no parents); each later step links to the event it
12224
+ * follows; and a [fusion](Self::record_fusion) links to *several* parents at
12225
+ * once: the heads of the trails it combines. This is the true shape of a
12226
+ * deduplicated entity: two recognizers are siblings, then a fusion joins them.
12227
+ * The events are stored in the order they were recorded, which is a
12228
+ * topological order of the DAG (a parent is always recorded before its
12229
+ * children).
12230
+ *
12231
+ * Two chains ride the DAG's edges:
12232
+ *
12233
+ * - a **confidence chain**, where each event's [`confidence`] is the entity's
12234
+ * effective score after it; the score flowing *in* is its parents'
12235
+ * confidence, so [`final_confidence`] and the full history are recoverable;
12236
+ * - a **hash chain**, where each event's [`hash`] folds its payload together
12237
+ * with its parents' hashes, so any edit, reorder, insertion, or deletion of
12238
+ * an earlier event breaks every event downstream. [`verify`] walks the DAG
12239
+ * and reports the first break.
12240
+ *
12241
+ * [`Entity`]: crate::entity::Entity
12242
+ * [`confidence`]: AuditEvent::confidence
12243
+ * [`hash`]: AuditEvent::hash
12244
+ * [`final_confidence`]: Self::final_confidence
12245
+ * [`verify`]: Self::verify
12246
+ */
12247
+ TabularAuditLog: components["schemas"]["TabularAuditEvent"][];
12248
+ /**
12249
+ * @description Detected piece of sensitive information within some medium.
12250
+ *
12251
+ * Generic over the [`Modality`] `M`, which is what makes the model
12252
+ * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
12253
+ * `Entity<Audio>`, and so on. The entity's location is the modality's
12254
+ * [`Location`] type, `M::Location`.
12255
+ *
12256
+ * # Birth and fusion
12257
+ *
12258
+ * A recognizer emits an entity directly, carrying a single recognition
12259
+ * [`AuditEvent`] (its own finding) in the entity's [`audit`] trail. When
12260
+ * several recognizers find the same thing, a fusion step (in
12261
+ * `elide`) combines their entities into one: the survivor's
12262
+ * [`location`] and [`confidence`] are the *fused* values, and every
12263
+ * contributing recognition event, plus a deduplication event, is
12264
+ * retained in its audit trail. The entity therefore carries its full
12265
+ * audit trail with it.
12266
+ *
12267
+ * [`Location`]: Modality::Location
12268
+ * [`AuditEvent`]: crate::entity::audit::AuditEvent
12269
+ * [`audit`]: Entity::audit
12270
+ * [`location`]: Entity::location
12271
+ * [`confidence`]: Entity::confidence
12272
+ */
12273
+ TabularEntity: {
12274
+ /**
12275
+ * @description Tamper-evident audit trail: every contributing detection, the fusion
12276
+ * event if any, and the redaction that hid it, as a hash-linked DAG.
12277
+ */
12278
+ audit: components["schemas"]["TabularAuditLog"];
12279
+ /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
12280
+ confidence: components["schemas"]["Confidence"];
12281
+ /**
12282
+ * @description Coreference identifier, if a recognizer resolved this entity as one
12283
+ * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
12284
+ * same real-world thing.
12285
+ */
12286
+ coref?: components["schemas"]["EntityCoRef"];
12287
+ /**
12288
+ * Format: uuid
12289
+ * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
12290
+ * when the entity is assembled.
12291
+ */
12292
+ id: string;
12293
+ /**
12294
+ * @description What kind of sensitive information this is (resolved via a
12295
+ * [`LabelCatalog`]).
12296
+ */
12297
+ label: components["schemas"]["LabelRef"];
12298
+ /**
12299
+ * @description The language of this entity's surrounding text, when a recognizer
12300
+ * resolved one. `None` when unknown or language-agnostic.
12301
+ */
12302
+ language?: string;
12303
+ /**
12304
+ * @description Location of the entity within the medium (fused, if it came from more
12305
+ * than one detection).
12306
+ */
12307
+ location: components["schemas"]["TabularLocation"];
12308
+ /**
12309
+ * @description Byte range of the match in the *recognized text* it was found in (the
12310
+ * OCR layout text, the audio transcript, or the text payload itself) —
12311
+ * the stable key back into that enrichment artifact, where the rich
12312
+ * context lives (which OCR block, which speaker) that the geometric
12313
+ * [`location`] cannot hold. `None` for entities not found via text
12314
+ * recognition (e.g. a VLM box). An audit key, not a coordinate: redaction
12315
+ * uses [`location`]; an audit uses this with the artifact.
12316
+ *
12317
+ * [`location`]: Entity::location
12318
+ */
12319
+ recognized_range?: components["schemas"]["Range_of_uint"];
12320
+ };
12321
+ /**
12322
+ * @description One recognized entity plus the optional reviewer override.
12323
+ *
12324
+ * The bound mirrors elide's [`Entity<M>`]: serialization needs
12325
+ * `M::Location` and `M::Data` (de)serializable, and JsonSchema
12326
+ * derivation needs them schema-able. All four modalities elide
12327
+ * ships satisfy these under the `serde` + `schema` features.
12328
+ */
12329
+ TabularEntityRecord: {
12330
+ /** @description The elide entity, as recognition produced it. */
12331
+ entity: components["schemas"]["TabularEntity"];
12332
+ /**
12333
+ * @description Reviewer-supplied redaction override.
12334
+ *
12335
+ * `None` means "use the matching policy rule's decision";
12336
+ * `Some(...)` overrides that rule for this specific entity
12337
+ * at apply time. Reviewer overrides take precedence over
12338
+ * every policy rule and inherit the authority of the
12339
+ * [`Review::policy_id`] they name — the audit event's
12340
+ * attribution stamps that policy so the trail names the
12341
+ * authority under which the override fired.
12342
+ */
12343
+ review?: components["schemas"]["Review"];
12017
12344
  };
12018
12345
  /**
12019
12346
  * @description Located, typed piece of context a recognizer may treat as in-context
@@ -12085,31 +12412,6 @@ interface components {
12085
12412
  */
12086
12413
  start_offset?: number;
12087
12414
  };
12088
- /**
12089
- * @description Full audit trail of an [`Entity`]: every [`Event`] in its life, in
12090
- * order.
12091
- *
12092
- * This is the model's answer to "full provenance": where Presidio keeps
12093
- * a shallow, optional, per-stage explanation that is stripped by
12094
- * default, a `Provenance` is always present and records the entity's
12095
- * *entire* life as an ordered list of events: each recognizer that
12096
- * found it, the deduplication that fused them, any confidence
12097
- * calibration, and the redaction that hid it. Nothing is collapsed:
12098
- * every recognizer keeps its own recognition event with its location
12099
- * and score.
12100
- *
12101
- * The events form a confidence chain (each event's [`after`] is the
12102
- * next's [`before`]) so the final confidence and its full history are
12103
- * always recoverable.
12104
- *
12105
- * [`Entity`]: crate::entity::Entity
12106
- * [`after`]: Event::after
12107
- * [`before`]: Event::before
12108
- */
12109
- TabularProvenance: {
12110
- /** @description Events, in the order they happened. */
12111
- events: components["schemas"]["TabularEvent"][];
12112
- };
12113
12415
  /** @description Operator spec a `redact` tabular rule carries. */
12114
12416
  TabularRedaction: {
12115
12417
  /** @constant */
@@ -12187,163 +12489,90 @@ interface components {
12187
12489
  payload?: unknown;
12188
12490
  };
12189
12491
  /**
12190
- * @description Run of text.
12492
+ * @description One node in an entity's audit DAG: a thing that happened, with its
12493
+ * effect on confidence and its tamper-evident links.
12191
12494
  *
12192
- * Either the payload a text recognizer inspects, or the value sliced out
12193
- * at an entity's location for an operator.
12495
+ * Events are recorded on an entity's [`AuditLog`], forming the full audit
12496
+ * trail of its life: each recognizer that found it, the deduplication that
12497
+ * fused them, any score calibration, and the redaction that hid it. The
12498
+ * uniform spine (who, resulting score, when) is the same for every event; the
12499
+ * [`kind`] carries the event-specific detail *and* the explanation of why the
12500
+ * event happened.
12194
12501
  *
12195
- * Held as a [`HipStr`] so short values inline and longer ones share a
12196
- * refcounted buffer, making cheap clones when one payload is passed to
12197
- * several recognizers.
12198
- */
12199
- TextData: string;
12200
- /**
12201
- * @description Detected piece of sensitive information within some medium.
12202
- *
12203
- * Generic over the [`Modality`] `M`, which is what makes the model
12204
- * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
12205
- * `Entity<Audio>`, and so on. The entity's location is the modality's
12206
- * [`Location`] type, `M::Location`.
12502
+ * Each event links to its [`parents`] by their [`hash`]: a birth event (a
12503
+ * recognizer's first detection) has no parents, a normal step has one, and a
12504
+ * [fusion](crate::entity::audit::AuditLog::record_fusion) has several. Its own
12505
+ * [`hash`] folds the
12506
+ * payload together with the parents' hashes, so altering any event breaks
12507
+ * every event downstream of it: [`AuditLog::verify`] walks the DAG and
12508
+ * reports the first break.
12207
12509
  *
12208
- * # Birth and fusion
12510
+ * `entity.confidence` always equals the [`confidence`] of the most recent
12511
+ * event. The confidence *flowing in* is not stored: it is the parents'
12512
+ * [`confidence`], recovered from the DAG.
12209
12513
  *
12210
- * A recognizer emits an entity directly, carrying a single recognition
12211
- * [`Event`] (its own finding) in the entity's [`provenance`]. When
12212
- * several recognizers find the same thing, a fusion step (in
12213
- * `elide`) combines their entities into one: the survivor's
12214
- * [`location`] and [`confidence`] are the *fused* values, and every
12215
- * contributing recognition event, plus a deduplication event, is
12216
- * retained in its provenance. The entity therefore carries its full
12217
- * audit trail with it.
12218
- *
12219
- * [`Location`]: Modality::Location
12220
- * [`Event`]: crate::entity::provenance::Event
12221
- * [`provenance`]: Entity::provenance
12222
- * [`location`]: Entity::location
12223
- * [`confidence`]: Entity::confidence
12514
+ * [`AuditLog`]: crate::entity::audit::AuditLog
12515
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
12516
+ * [`AuditLog::verify`]: crate::entity::audit::AuditLog::verify
12517
+ * [`kind`]: AuditEvent::kind
12518
+ * [`parents`]: AuditEvent::parents
12519
+ * [`hash`]: AuditEvent::hash
12520
+ * [`confidence`]: AuditEvent::confidence
12224
12521
  */
12225
- TextEntity: {
12226
- /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
12227
- confidence: components["schemas"]["Confidence"];
12228
- /**
12229
- * @description Coreference identifier, if a recognizer resolved this entity as one
12230
- * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
12231
- * same real-world thing.
12232
- */
12233
- coref?: components["schemas"]["EntityCoRef"];
12522
+ TextAuditEvent: {
12234
12523
  /**
12235
- * Format: uuid
12236
- * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
12237
- * when the entity is assembled.
12238
- */
12239
- id: string;
12240
- /**
12241
- * @description What kind of sensitive information this is (resolved via a
12242
- * [`LabelCatalog`]).
12524
+ * @description Confidence after this event: the entity's effective confidence once it
12525
+ * has happened.
12243
12526
  */
12244
- label: components["schemas"]["LabelRef"];
12245
- /**
12246
- * @description The language of this entity's surrounding text, when a recognizer
12247
- * resolved one. `None` when unknown or language-agnostic.
12248
- */
12249
- language?: string;
12250
- /**
12251
- * @description Location of the entity within the medium (fused, if it came from more
12252
- * than one detection).
12253
- */
12254
- location: components["schemas"]["TextLocation"];
12255
- /**
12256
- * @description Detection audit trail: every contributing detection and the fusion
12257
- * event, if any.
12258
- */
12259
- provenance: components["schemas"]["TextProvenance"];
12527
+ confidence: components["schemas"]["Confidence"];
12260
12528
  /**
12261
- * @description Byte range of the match in the *recognized text* it was found in (the
12262
- * OCR layout text, the audio transcript, or the text payload itself) —
12263
- * the stable key back into that enrichment artifact, where the rich
12264
- * context lives (which OCR block, which speaker) that the geometric
12265
- * [`location`] cannot hold. `None` for entities not found via text
12266
- * recognition (e.g. a VLM box). Provenance, not a coordinate: redaction
12267
- * uses [`location`]; an audit uses this with the artifact.
12529
+ * @description This event's hash, over its payload and its parents' hashes. Assigned by
12530
+ * [`AuditLog`] when the event is recorded; read it through
12531
+ * [`hash`](Self::hash). Recomputing it is how the DAG is verified.
12268
12532
  *
12269
- * [`location`]: Entity::location
12270
- */
12271
- recognized_range?: components["schemas"]["Range_of_uint"];
12272
- };
12273
- /**
12274
- * @description One recognized entity plus the optional reviewer override.
12275
- *
12276
- * The bound mirrors elide's [`Entity<M>`]: serialization needs
12277
- * `M::Location` and `M::Data` (de)serializable, and JsonSchema
12278
- * derivation needs them schema-able. All four modalities elide
12279
- * ships satisfy these under the `serde` + `schema` features.
12280
- */
12281
- TextEntityRecord: {
12282
- /** @description The elide entity, as recognition produced it. */
12283
- entity: components["schemas"]["TextEntity"];
12284
- /**
12285
- * @description Reviewer-supplied redaction override.
12533
+ * Not publicly settable: only [`AuditLog`] assigns it, so a caller cannot
12534
+ * forge a self-consistent event outside the recording path.
12286
12535
  *
12287
- * `None` means "use the matching policy rule's decision";
12288
- * `Some(...)` overrides that rule for this specific entity
12289
- * at apply time. Reviewer overrides take precedence over
12290
- * every policy rule and inherit the authority of the
12291
- * [`Review::policy_id`] they name — the audit event's
12292
- * attribution stamps that policy so the trail names the
12293
- * authority under which the override fired.
12536
+ * [`AuditLog`]: crate::entity::audit::AuditLog
12294
12537
  */
12295
- review?: components["schemas"]["Review"];
12296
- };
12297
- /**
12298
- * @description One thing that happened to an entity, with its effect on confidence.
12299
- *
12300
- * Events are recorded in order on an entity's [`Provenance`], forming
12301
- * the full audit trail of its life: each recognizer that found it, the
12302
- * deduplication that fused them, any score calibration, and the
12303
- * redaction that hid it. The uniform spine (who, before/after score,
12304
- * when, why) is the same for every event; the [`kind`] carries the
12305
- * event-specific detail.
12306
- *
12307
- * `entity.confidence` always equals the [`after`] of the most recent
12308
- * event.
12309
- *
12310
- * [`Provenance`]: crate::entity::provenance::Provenance
12311
- * [`kind`]: Event::kind
12312
- * [`after`]: Event::after
12313
- */
12314
- TextEvent: {
12315
- /** @description Confidence after this event. */
12316
- after: components["schemas"]["Confidence"];
12317
- /** @description When the event happened (UTC). */
12318
- at: string;
12538
+ hash: components["schemas"]["AuditHash"];
12539
+ /** @description Kind of event, with its event-specific detail and its rationale. */
12540
+ kind: components["schemas"]["TextAuditKind"];
12319
12541
  /**
12320
- * @description Confidence before this event, if there was a prior value. `None` on
12321
- * the first (birth) event.
12542
+ * @description The events this one follows, by their hash. Empty for a birth event, one
12543
+ * entry for a normal step, several for a fusion. Assigned by [`AuditLog`]
12544
+ * when the event is recorded; read it through [`parents`](Self::parents).
12545
+ *
12546
+ * Not publicly settable: the links are the tamper-evident structure, so
12547
+ * only [`AuditLog::record`] / [`AuditLog::record_fusion`] assign them.
12548
+ *
12549
+ * [`AuditLog`]: crate::entity::audit::AuditLog
12550
+ * [`AuditLog::record`]: crate::entity::audit::AuditLog::record
12551
+ * [`AuditLog::record_fusion`]: crate::entity::audit::AuditLog::record_fusion
12322
12552
  */
12323
- before?: components["schemas"]["Confidence"];
12324
- /** @description Kind of event, with its event-specific detail. */
12325
- kind: components["schemas"]["TextEventKind"];
12326
- /** @description Free-text explanation of what the event did and why. */
12327
- reason: string;
12553
+ parents: components["schemas"]["AuditHash"][];
12328
12554
  /**
12329
12555
  * @description Who produced this event: a recognizer name, a deduplication strategy,
12330
12556
  * an operator, or whatever acted.
12331
12557
  */
12332
12558
  source: string;
12559
+ /** @description When the event happened (UTC). */
12560
+ timestamp: string;
12333
12561
  };
12334
12562
  /**
12335
- * @description Kind of an [`Event`], carrying its event-specific detail.
12563
+ * @description Kind of an [`AuditEvent`], carrying its event-specific detail and the
12564
+ * rationale for why it happened.
12336
12565
  *
12337
12566
  * `#[non_exhaustive]`: new event kinds (verification, annotation, …)
12338
12567
  * can be added compatibly. The recognition kinds ([`Pattern`],
12339
12568
  * [`Model`]) carry the matched [`Location`]; the rest carry their own
12340
12569
  * data.
12341
12570
  *
12342
- * [`Pattern`]: EventKind::Pattern
12343
- * [`Model`]: EventKind::Model
12571
+ * [`Pattern`]: AuditKind::Pattern
12572
+ * [`Model`]: AuditKind::Model
12344
12573
  * [`Location`]: Modality::Location
12345
12574
  */
12346
- TextEventKind: {
12575
+ TextAuditKind: {
12347
12576
  /** @constant */
12348
12577
  kind: "pattern";
12349
12578
  /** @description Where the recognizer matched. */
@@ -12407,7 +12636,7 @@ interface components {
12407
12636
  * it is the keyword resolved through the modality's [`locate`] (a
12408
12637
  * pixel box for image, a time span for audio, the byte range for
12409
12638
  * text/tabular). `None` when the keyword's stream range could not be
12410
- * placed symmetric with a match the recognizer itself drops.
12639
+ * placed, symmetric with a match the recognizer itself drops.
12411
12640
  *
12412
12641
  * [`locate`]: crate::modality::TextRecognizable::locate
12413
12642
  */
@@ -12425,12 +12654,169 @@ interface components {
12425
12654
  /** @description How much the output leaks about the original. */
12426
12655
  leak_profile: components["schemas"]["LeakProfile"];
12427
12656
  /**
12428
- * @description Which selection rule chose this operator the automatic "why"
12657
+ * @description Which selection rule chose this operator: the automatic "why"
12429
12658
  * (matched a label, a tag, a predicate, or the fallback).
12430
12659
  */
12431
12660
  matched_by: components["schemas"]["RuleMatch"];
12432
12661
  /** @description Which operator (name + version) ran. */
12433
12662
  operator: components["schemas"]["OperatorId"];
12663
+ /**
12664
+ * @description BLAKE3 digest of the original text the operator hid, when the
12665
+ * redaction layer recorded it. Proves *what* was redacted without
12666
+ * storing the plaintext; `None` when the operator did not capture it.
12667
+ */
12668
+ span_hash?: components["schemas"]["AuditHash"];
12669
+ /**
12670
+ * Format: uint32
12671
+ * @description Byte length of the original text the operator hid, paired with
12672
+ * [`span_hash`](Self::Redaction::span_hash). `None` when not captured.
12673
+ */
12674
+ span_length?: number;
12675
+ };
12676
+ /**
12677
+ * @description Full audit trail of an [`Entity`]: every [`AuditEvent`] in its life, as a
12678
+ * tamper-evident DAG.
12679
+ *
12680
+ * Where Presidio keeps a shallow, optional, per-stage explanation that is
12681
+ * stripped by default, an `AuditLog` is always present and records the
12682
+ * entity's *entire* life: each recognizer that found it, the deduplication
12683
+ * that fused them, any confidence calibration, and the redaction that hid it.
12684
+ * Nothing is collapsed: every recognizer keeps its own recognition event with
12685
+ * its location and score.
12686
+ *
12687
+ * The events form a **directed acyclic graph**, not a flat list. A recognizer
12688
+ * records a birth event (no parents); each later step links to the event it
12689
+ * follows; and a [fusion](Self::record_fusion) links to *several* parents at
12690
+ * once: the heads of the trails it combines. This is the true shape of a
12691
+ * deduplicated entity: two recognizers are siblings, then a fusion joins them.
12692
+ * The events are stored in the order they were recorded, which is a
12693
+ * topological order of the DAG (a parent is always recorded before its
12694
+ * children).
12695
+ *
12696
+ * Two chains ride the DAG's edges:
12697
+ *
12698
+ * - a **confidence chain**, where each event's [`confidence`] is the entity's
12699
+ * effective score after it; the score flowing *in* is its parents'
12700
+ * confidence, so [`final_confidence`] and the full history are recoverable;
12701
+ * - a **hash chain**, where each event's [`hash`] folds its payload together
12702
+ * with its parents' hashes, so any edit, reorder, insertion, or deletion of
12703
+ * an earlier event breaks every event downstream. [`verify`] walks the DAG
12704
+ * and reports the first break.
12705
+ *
12706
+ * [`Entity`]: crate::entity::Entity
12707
+ * [`confidence`]: AuditEvent::confidence
12708
+ * [`hash`]: AuditEvent::hash
12709
+ * [`final_confidence`]: Self::final_confidence
12710
+ * [`verify`]: Self::verify
12711
+ */
12712
+ TextAuditLog: components["schemas"]["TextAuditEvent"][];
12713
+ /**
12714
+ * @description Run of text.
12715
+ *
12716
+ * Either the payload a text recognizer inspects, or the value sliced out
12717
+ * at an entity's location for an operator.
12718
+ *
12719
+ * Held as a [`HipStr`] so short values inline and longer ones share a
12720
+ * refcounted buffer, making cheap clones when one payload is passed to
12721
+ * several recognizers.
12722
+ */
12723
+ TextData: string;
12724
+ /**
12725
+ * @description Detected piece of sensitive information within some medium.
12726
+ *
12727
+ * Generic over the [`Modality`] `M`, which is what makes the model
12728
+ * multimodal: a text pipeline yields `Entity<Text>`, an audio pipeline
12729
+ * `Entity<Audio>`, and so on. The entity's location is the modality's
12730
+ * [`Location`] type, `M::Location`.
12731
+ *
12732
+ * # Birth and fusion
12733
+ *
12734
+ * A recognizer emits an entity directly, carrying a single recognition
12735
+ * [`AuditEvent`] (its own finding) in the entity's [`audit`] trail. When
12736
+ * several recognizers find the same thing, a fusion step (in
12737
+ * `elide`) combines their entities into one: the survivor's
12738
+ * [`location`] and [`confidence`] are the *fused* values, and every
12739
+ * contributing recognition event, plus a deduplication event, is
12740
+ * retained in its audit trail. The entity therefore carries its full
12741
+ * audit trail with it.
12742
+ *
12743
+ * [`Location`]: Modality::Location
12744
+ * [`AuditEvent`]: crate::entity::audit::AuditEvent
12745
+ * [`audit`]: Entity::audit
12746
+ * [`location`]: Entity::location
12747
+ * [`confidence`]: Entity::confidence
12748
+ */
12749
+ TextEntity: {
12750
+ /**
12751
+ * @description Tamper-evident audit trail: every contributing detection, the fusion
12752
+ * event if any, and the redaction that hid it, as a hash-linked DAG.
12753
+ */
12754
+ audit: components["schemas"]["TextAuditLog"];
12755
+ /** @description Effective confidence in `0.0..=1.0` (fused, if applicable). */
12756
+ confidence: components["schemas"]["Confidence"];
12757
+ /**
12758
+ * @description Coreference identifier, if a recognizer resolved this entity as one
12759
+ * mention of a cluster. Entities sharing an [`EntityCoRef`] denote the
12760
+ * same real-world thing.
12761
+ */
12762
+ coref?: components["schemas"]["EntityCoRef"];
12763
+ /**
12764
+ * Format: uuid
12765
+ * @description Stable unique identity for this entity (time-ordered UUIDv7), minted
12766
+ * when the entity is assembled.
12767
+ */
12768
+ id: string;
12769
+ /**
12770
+ * @description What kind of sensitive information this is (resolved via a
12771
+ * [`LabelCatalog`]).
12772
+ */
12773
+ label: components["schemas"]["LabelRef"];
12774
+ /**
12775
+ * @description The language of this entity's surrounding text, when a recognizer
12776
+ * resolved one. `None` when unknown or language-agnostic.
12777
+ */
12778
+ language?: string;
12779
+ /**
12780
+ * @description Location of the entity within the medium (fused, if it came from more
12781
+ * than one detection).
12782
+ */
12783
+ location: components["schemas"]["TextLocation"];
12784
+ /**
12785
+ * @description Byte range of the match in the *recognized text* it was found in (the
12786
+ * OCR layout text, the audio transcript, or the text payload itself) —
12787
+ * the stable key back into that enrichment artifact, where the rich
12788
+ * context lives (which OCR block, which speaker) that the geometric
12789
+ * [`location`] cannot hold. `None` for entities not found via text
12790
+ * recognition (e.g. a VLM box). An audit key, not a coordinate: redaction
12791
+ * uses [`location`]; an audit uses this with the artifact.
12792
+ *
12793
+ * [`location`]: Entity::location
12794
+ */
12795
+ recognized_range?: components["schemas"]["Range_of_uint"];
12796
+ };
12797
+ /**
12798
+ * @description One recognized entity plus the optional reviewer override.
12799
+ *
12800
+ * The bound mirrors elide's [`Entity<M>`]: serialization needs
12801
+ * `M::Location` and `M::Data` (de)serializable, and JsonSchema
12802
+ * derivation needs them schema-able. All four modalities elide
12803
+ * ships satisfy these under the `serde` + `schema` features.
12804
+ */
12805
+ TextEntityRecord: {
12806
+ /** @description The elide entity, as recognition produced it. */
12807
+ entity: components["schemas"]["TextEntity"];
12808
+ /**
12809
+ * @description Reviewer-supplied redaction override.
12810
+ *
12811
+ * `None` means "use the matching policy rule's decision";
12812
+ * `Some(...)` overrides that rule for this specific entity
12813
+ * at apply time. Reviewer overrides take precedence over
12814
+ * every policy rule and inherit the authority of the
12815
+ * [`Review::policy_id`] they name — the audit event's
12816
+ * attribution stamps that policy so the trail names the
12817
+ * authority under which the override fired.
12818
+ */
12819
+ review?: components["schemas"]["Review"];
12434
12820
  };
12435
12821
  /**
12436
12822
  * @description Located, typed piece of context a recognizer may treat as in-context
@@ -12479,31 +12865,6 @@ interface components {
12479
12865
  */
12480
12866
  start: number;
12481
12867
  };
12482
- /**
12483
- * @description Full audit trail of an [`Entity`]: every [`Event`] in its life, in
12484
- * order.
12485
- *
12486
- * This is the model's answer to "full provenance": where Presidio keeps
12487
- * a shallow, optional, per-stage explanation that is stripped by
12488
- * default, a `Provenance` is always present and records the entity's
12489
- * *entire* life as an ordered list of events: each recognizer that
12490
- * found it, the deduplication that fused them, any confidence
12491
- * calibration, and the redaction that hid it. Nothing is collapsed:
12492
- * every recognizer keeps its own recognition event with its location
12493
- * and score.
12494
- *
12495
- * The events form a confidence chain (each event's [`after`] is the
12496
- * next's [`before`]) so the final confidence and its full history are
12497
- * always recoverable.
12498
- *
12499
- * [`Entity`]: crate::entity::Entity
12500
- * [`after`]: Event::after
12501
- * [`before`]: Event::before
12502
- */
12503
- TextProvenance: {
12504
- /** @description Events, in the order they happened. */
12505
- events: components["schemas"]["TextEvent"][];
12506
- };
12507
12868
  /** @description Operator spec a `redact` text rule carries. */
12508
12869
  TextRedaction: {
12509
12870
  /** @constant */
@@ -13229,6 +13590,8 @@ type RuleMatch = Schemas$16["RuleMatch"];
13229
13590
  type ModelEvent = Schemas$16["ModelEvent"];
13230
13591
  type PatternEvent = Schemas$16["PatternEvent"];
13231
13592
  type OperatorId = Schemas$16["OperatorId"];
13593
+ type AuditHash = Schemas$16["AuditHash"];
13594
+ type Category = Schemas$16["Category"];
13232
13595
  /** Half-open `[start, end)` index range. Generated name; a plain uint range. */
13233
13596
  type RangeOfUint = Schemas$16["Range_of_uint"];
13234
13597
  type BoundingBox = Schemas$16["BoundingBox"];
@@ -13238,35 +13601,35 @@ type Dimensions = Schemas$16["Dimensions"];
13238
13601
  type TimeSpan = Schemas$16["TimeSpan"];
13239
13602
  type TextEntity = Schemas$16["TextEntity"];
13240
13603
  type TextEntityRecord = Schemas$16["TextEntityRecord"];
13241
- type TextEvent = Schemas$16["TextEvent"];
13242
- type TextEventKind = Schemas$16["TextEventKind"];
13604
+ type TextAuditEvent = Schemas$16["TextAuditEvent"];
13605
+ type TextAuditKind = Schemas$16["TextAuditKind"];
13243
13606
  type TextHint = Schemas$16["TextHint"];
13244
13607
  type TextLocation = Schemas$16["TextLocation"];
13245
- type TextProvenance = Schemas$16["TextProvenance"];
13608
+ type TextAuditLog = Schemas$16["TextAuditLog"];
13246
13609
  type TextData = Schemas$16["TextData"];
13247
13610
  type ImageEntity = Schemas$16["ImageEntity"];
13248
13611
  type ImageEntityRecord = Schemas$16["ImageEntityRecord"];
13249
- type ImageEvent = Schemas$16["ImageEvent"];
13250
- type ImageEventKind = Schemas$16["ImageEventKind"];
13612
+ type ImageAuditEvent = Schemas$16["ImageAuditEvent"];
13613
+ type ImageAuditKind = Schemas$16["ImageAuditKind"];
13251
13614
  type ImageHint = Schemas$16["ImageHint"];
13252
13615
  type ImageLocation = Schemas$16["ImageLocation"];
13253
- type ImageProvenance = Schemas$16["ImageProvenance"];
13616
+ type ImageAuditLog = Schemas$16["ImageAuditLog"];
13254
13617
  type ImageData = Schemas$16["ImageData"];
13255
13618
  type AudioEntity = Schemas$16["AudioEntity"];
13256
13619
  type AudioEntityRecord = Schemas$16["AudioEntityRecord"];
13257
- type AudioEvent = Schemas$16["AudioEvent"];
13258
- type AudioEventKind = Schemas$16["AudioEventKind"];
13620
+ type AudioAuditEvent = Schemas$16["AudioAuditEvent"];
13621
+ type AudioAuditKind = Schemas$16["AudioAuditKind"];
13259
13622
  type AudioHint = Schemas$16["AudioHint"];
13260
13623
  type AudioLocation = Schemas$16["AudioLocation"];
13261
- type AudioProvenance = Schemas$16["AudioProvenance"];
13624
+ type AudioAuditLog = Schemas$16["AudioAuditLog"];
13262
13625
  type AudioData = Schemas$16["AudioData"];
13263
13626
  type TabularEntity = Schemas$16["TabularEntity"];
13264
13627
  type TabularEntityRecord = Schemas$16["TabularEntityRecord"];
13265
- type TabularEvent = Schemas$16["TabularEvent"];
13266
- type TabularEventKind = Schemas$16["TabularEventKind"];
13628
+ type TabularAuditEvent = Schemas$16["TabularAuditEvent"];
13629
+ type TabularAuditKind = Schemas$16["TabularAuditKind"];
13267
13630
  type TabularHint = Schemas$16["TabularHint"];
13268
13631
  type TabularLocation = Schemas$16["TabularLocation"];
13269
- type TabularProvenance = Schemas$16["TabularProvenance"];
13632
+ type TabularAuditLog = Schemas$16["TabularAuditLog"];
13270
13633
  //#endregion
13271
13634
  //#region src/datatypes/auth.d.ts
13272
13635
  type Schemas$15 = components["schemas"];
@@ -13400,8 +13763,12 @@ type CreatePolicy = Schemas$4["CreatePolicy"];
13400
13763
  type UpdatePolicy = Schemas$4["UpdatePolicy"];
13401
13764
  type PolicyRule = Schemas$4["PolicyRule"];
13402
13765
  type PolicyTemplate = Schemas$4["PolicyTemplate"];
13766
+ type HipaaDeidentification = Schemas$4["HipaaDeidentification"];
13403
13767
  type HipaaDeidMethod = Schemas$4["HipaaDeidMethod"];
13768
+ type HipaaAccountNumbers = Schemas$4["HipaaAccountNumbers"];
13769
+ type GdprArticle9 = Schemas$4["GdprArticle9"];
13404
13770
  type GdprArticle9Treatment = Schemas$4["GdprArticle9Treatment"];
13771
+ type GdprSensitiveScope = Schemas$4["GdprSensitiveScope"];
13405
13772
  type PciDssPart = Schemas$4["PciDssPart"];
13406
13773
  type PciPanRender = Schemas$4["PciPanRender"];
13407
13774
  type Predicate = Schemas$4["Predicate"];
@@ -13473,5 +13840,5 @@ type Retention = Schemas["Retention"];
13473
13840
  type RetentionSettings = Schemas["RetentionSettings"];
13474
13841
  type RetentionOverride = Schemas["RetentionOverride"];
13475
13842
  //#endregion
13476
- export { ModalityRedactions as $, AudioEventKind as $n, ConnectionActivityParams as $r, InvitePage as $t, PipelineRun as A, LlmConfig as An, TabularEventKind as Ar, Notification as At, CreatePolicy as B, SyncTriggerType as Bn, TextLocation as Br, UnreadCountEvent as Bt, LanguageProvenance as C, ConnectionPage as Cn, Polygon as Cr, UpdatePipeline as Ct, ScopeParams as D, ConnectionsQuery as Dn, TabularEntity as Dr, MarkedReadStatus as Dt, ScopeMetadata as E, ConnectionVerification as En, RuleMatch as Er, ConnectionSyncFailedParams as Et, RunStatusEvent as F, SyncDeletionPolicy as Fn, TextEntity as Fr, PipelineRunAnalyzedParams as Ft, ImageRedaction as G, AuthToken as Gn, ApiTokenType as Gr, MemberPage as Gt, DateStyle as H, LabelCatalog as Hn, TimeSpan as Hr, UpdateNotificationSettings as Ht, AudioRedaction as I, SyncMode as In, TextEntityRecord as Ir, PipelineRunCompletedParams as It, LabelGroup as J, Attribution as Jn, TokenExpiration as Jr, CreateInvite as Jt, Label as K, Login as Kn, ApiTokenWithJWT as Kr, MemberSortField as Kt, ClampBucket as L, SyncSchedule as Ln, TextEvent as Lr, PipelineRunFailedParams as Lt, PipelineRunStatus as M, S3Credentials as Mn, TabularLocation as Mr, NotificationPage as Mt, PipelineRunsQuery as N, StorageConfig as Nn, TabularProvenance as Nr, NotificationPayload as Nt, Audit as O, CreateConnection as On, TabularEntityRecord as Or, MemberInvitedParams as Ot, RunMetadata as P, SyncConnection as Pn, TextData as Pr, NotificationSettings as Pt, LocalizedText as Q, AudioEvent as Qn, ActivityPayload as Qr, InviteExpiration as Qt, Color as R, SyncScheduleInput as Rn, TextEventKind as Rr, SystemAnnouncementParams as Rt, Language as S, ConnectionConfig as Sn, Point as Sr, PipelineTriggerType as St, Languages as T, ConnectionSyncPage as Tn, Review as Tr, ConnectionSyncCompletedParams as Tt, GdprArticle9Treatment as U, RecognizerCatalog as Un, ApiToken as Ur, ListMembers as Ut, DateGranularity as V, UpdateConnection as Vn, TextProvenance as Vr, UnreadStatus as Vt, HipaaDeidMethod as W, RegisteredRecognizer as Wn, ApiTokenPage as Wr, Member as Wt, Labels as X, AudioEntity as Xn, Activity as Xr, Invite as Xt, LabelLocale as Y, AudioData as Yn, UpdateApiToken as Yr, GenerateInviteCode as Yt, LanguageTag as Z, AudioEntityRecord as Zn, ActivityPage as Zr, InviteCode as Zt, WebhookPage as _, ErrorResponse as _n, LeakProfile as _r, PipelineDefinition as _t, RetentionSettings as a, PolicyActivityParams as ai, ReplyInvite as an, Dimensions as ar, PolicySummary as at, Confidence as b, AzureCredentials as bn, OperatorId as br, PipelineSummary as bt, WorkspacePage as c, Account as ci, Health as cn, EntityGroup as cr, Predicate as ct, CreateWebhook as d, UpdateAccount as di, FileKind as dn, ImageEntityRecord as dr, TerminalFallback as dt, FileActivityParams as ei, InvitePreview as en, AudioHint as er, PciDssPart as et, TestWebhook as f, paths as fi, FilePage as fn, ImageEvent as fr, TextRedaction as ft, WebhookEvent as g, UpdateFile as gn, ImageProvenance as gr, Pipeline as gt, WebhookCreated as h, ModalityToken as hn, ImageLocation as hr, CreatePipeline as ht, RetentionOverride as i, PipelineRunActivityParams as ii, ListInvites as in, BoundingBox as ir, PolicyRule as it, PipelineRunPage as j, OpenAiCredentials as jn, TabularHint as jr, NotificationEvent as jt, CreatePipelineRun as k, GcsCredentials as kn, TabularEvent as kr, MemberJoinedParams as kt, WorkspaceRole as l, AccountRef as li, HealthStatus as ln, ImageData as lr, Sha2Algorithm as lt, Webhook as m, ListFiles as mn, ImageHint as mr, Waveform as mt, OcrPolicy as n, MemberActivityParams as ni, InviteSortField as nn, AudioProvenance as nr, Policy as nt, UpdateWorkspace as o, WebhookActivityParams as oi, SortOrder as on, Dpi as or, PolicySummaryPage as ot, UpdateWebhook as p, FormatToken as pn, ImageEventKind as pr, UpdatePolicy as pt, LabelEntry as q, Signup as qn, CreateApiToken as qr, UpdateMember as qt, Retention as r, PipelineActivityParams as ri, InviteStatus as rn, AuditContext as rr, PolicyDefinition as rt, Workspace as s, WorkspaceActivityParams as si, ComponentHealth as sn, EntityCoRef as sr, PolicyTemplate as st, CreateWorkspace as t, InviteActivityParams as ti, InviteSent as tn, AudioLocation as tr, PciPanRender as tt, WorkspaceSettings as u, PublicAccount as ui, File as un, ImageEntity as ur, TabularRedaction as ut, WebhookResult as v, ValidationErrorDetail as vn, ModelEvent as vr, PipelineFilter as vt, LanguageSpan as w, ConnectionSync as wn, RangeOfUint as wr, CursorPagination as wt, CountryCode as x, Connection as xn, PatternEvent as xr, PipelineSummaryPage as xt, WebhookStatus as y, AnthropicCredentials as yn, OcrMode as yr, PipelineStatus as yt, ConfidenceThreshold as z, SyncStatus as zn, TextHint as zr, SystemReportParams as zt };
13477
- //# sourceMappingURL=index-Cijg5CMy.d.ts.map
13843
+ export { LabelLocale as $, AudioAuditEvent as $n, CreateApiToken as $r, GenerateInviteCode as $t, PipelineRun as A, ConnectionVerification as An, RangeOfUint as Ar, ConnectionSyncFailedParams as At, CreatePolicy as B, SyncMode as Bn, TextAuditEvent as Br, PipelineRunCompletedParams as Bt, LanguageProvenance as C, AnthropicCredentials as Cn, LeakProfile as Cr, PipelineStatus as Ct, ScopeParams as D, ConnectionPage as Dn, PatternEvent as Dr, UpdatePipeline as Dt, ScopeMetadata as E, ConnectionConfig as En, OperatorId as Er, PipelineTriggerType as Et, RunStatusEvent as F, OpenAiCredentials as Fn, TabularAuditLog as Fr, NotificationEvent as Ft, GdprSensitiveScope as G, UpdateConnection as Gn, TextEntityRecord as Gr, UnreadStatus as Gt, DateStyle as H, SyncScheduleInput as Hn, TextAuditLog as Hr, SystemAnnouncementParams as Ht, AudioRedaction as I, S3Credentials as In, TabularEntity as Ir, NotificationPage as It, HipaaDeidentification as J, RegisteredRecognizer as Jn, TimeSpan as Jr, Member as Jt, HipaaAccountNumbers as K, LabelCatalog as Kn, TextHint as Kr, UpdateNotificationSettings as Kt, ClampBucket as L, StorageConfig as Ln, TabularEntityRecord as Lr, NotificationPayload as Lt, PipelineRunStatus as M, CreateConnection as Mn, RuleMatch as Mr, MemberInvitedParams as Mt, PipelineRunsQuery as N, GcsCredentials as Nn, TabularAuditEvent as Nr, MemberJoinedParams as Nt, Audit as O, ConnectionSync as On, Point as Or, CursorPagination as Ot, RunMetadata as P, LlmConfig as Pn, TabularAuditKind as Pr, Notification as Pt, LabelGroup as Q, Attribution as Qn, ApiTokenWithJWT as Qr, CreateInvite as Qt, Color as R, SyncConnection as Rn, TabularHint as Rr, NotificationSettings as Rt, Language as S, ValidationErrorDetail as Sn, ImageLocation as Sr, PipelineFilter as St, Languages as T, Connection as Tn, OcrMode as Tr, PipelineSummaryPage as Tt, GdprArticle9 as U, SyncStatus as Un, TextData as Ur, SystemReportParams as Ut, DateGranularity as V, SyncSchedule as Vn, TextAuditKind as Vr, PipelineRunFailedParams as Vt, GdprArticle9Treatment as W, SyncTriggerType as Wn, TextEntity as Wr, UnreadCountEvent as Wt, Label as X, Login as Xn, ApiTokenPage as Xr, MemberSortField as Xt, ImageRedaction as Y, AuthToken as Yn, ApiToken as Yr, MemberPage as Yt, LabelEntry as Z, Signup as Zn, ApiTokenType as Zr, UpdateMember as Zt, WebhookPage as _, UpdateAccount as _i, FormatToken as _n, ImageAuditLog as _r, UpdatePolicy as _t, RetentionSettings as a, ConnectionActivityParams as ai, InviteSent as an, AudioHint as ar, PciPanRender as at, Confidence as b, UpdateFile as bn, ImageEntityRecord as br, Pipeline as bt, WorkspacePage as c, MemberActivityParams as ci, ListInvites as cn, AuditHash as cr, PolicyRule as ct, CreateWebhook as d, PolicyActivityParams as di, ComponentHealth as dn, Dimensions as dr, PolicyTemplate as dt, TokenExpiration as ei, Invite as en, AudioAuditKind as er, Labels as et, TestWebhook as f, WebhookActivityParams as fi, Health as fn, Dpi as fr, Predicate as ft, WebhookEvent as g, PublicAccount as gi, FilePage as gn, ImageAuditKind as gr, TextRedaction as gt, WebhookCreated as h, AccountRef as hi, FileKind as hn, ImageAuditEvent as hr, TerminalFallback as ht, RetentionOverride as i, ActivityPayload as ii, InvitePreview as in, AudioEntityRecord as ir, PciDssPart as it, PipelineRunPage as j, ConnectionsQuery as jn, Review as jr, MarkedReadStatus as jt, CreatePipelineRun as k, ConnectionSyncPage as kn, Polygon as kr, ConnectionSyncCompletedParams as kt, WorkspaceRole as l, PipelineActivityParams as li, ReplyInvite as ln, BoundingBox as lr, PolicySummary as lt, Webhook as m, Account as mi, File as mn, EntityGroup as mr, TabularRedaction as mt, OcrPolicy as n, Activity as ni, InviteExpiration as nn, AudioData as nr, LocalizedText as nt, UpdateWorkspace as o, FileActivityParams as oi, InviteSortField as on, AudioLocation as or, Policy as ot, UpdateWebhook as p, WorkspaceActivityParams as pi, HealthStatus as pn, EntityCoRef as pr, Sha2Algorithm as pt, HipaaDeidMethod as q, RecognizerCatalog as qn, TextLocation as qr, ListMembers as qt, Retention as r, ActivityPage as ri, InvitePage as rn, AudioEntity as rr, ModalityRedactions as rt, Workspace as s, InviteActivityParams as si, InviteStatus as sn, AuditContext as sr, PolicyDefinition as st, CreateWorkspace as t, UpdateApiToken as ti, InviteCode as tn, AudioAuditLog as tr, LanguageTag as tt, WorkspaceSettings as u, PipelineRunActivityParams as ui, SortOrder as un, Category as ur, PolicySummaryPage as ut, WebhookResult as v, paths as vi, ListFiles as vn, ImageData as vr, Waveform as vt, LanguageSpan as w, AzureCredentials as wn, ModelEvent as wr, PipelineSummary as wt, CountryCode as x, ErrorResponse as xn, ImageHint as xr, PipelineDefinition as xt, WebhookStatus as y, ModalityToken as yn, ImageEntity as yr, CreatePipeline as yt, ConfidenceThreshold as z, SyncDeletionPolicy as zn, TabularLocation as zr, PipelineRunAnalyzedParams as zt };
13844
+ //# sourceMappingURL=index-Zd5G8h44.d.ts.map