# `semantic.ai_personal_data_not_allowed`

Your code sends a model personal data of a kind, such as health records, that the app's `ai:` settings don't allow it to send.

Area 21, [AI](/docs/ai.md); not declinable; the next step is usually the human's.

## Why Jadpo refuses it

By default your app may send a model no personal data at all. Each
kind it sends, its category, is listed once in `app.jadpo`, under
`ai: { personal_data: { allowed: } }`, so a reviewer sees in one place
what the provider is given. A field's category comes from its
`personal:` mark, or from a standard type that is always personal data,
such as an `NhsNumber`.

The compiler follows each value a prompt is built from back to the
fields it was read from. A marked field copied into a variable, built
into text or passed through a function keeps its category. The error
names the field and the category, never a value.

Jadpo won't list a category for you. Sending health records to a
provider is a privacy decision, and it is yours.

## What it looks like

The clinic allows `identifying` data, and its handover summary sends a
patient's notes, which are `health`, through a variable.

app.jadpo:

```jadpo
application {
    connections: {
        local_model: {
            driver: Driver.openai_compatible
            url: config.model_url
        }
    }
    ai: {
        connection: local_model
        models: {
            default: config.drafting_model
        }
        limits: {
            per_day: {
                tokens: 2000000
            }
        }
        personal_data: {
            allowed: [PersonalData.identifying]
        }
    }
}
```




domains/clinic/entities/patient.jadpo:

```jadpo
use clinic/types { ClinicalNote }

/// A patient of the clinic.
entity Patient {
    id: Uuid
    patient_nhs_number: NhsNumber {
        personal: PersonalData.government_id
        to_models: false
    }
    notes: ClinicalNote {
        personal: PersonalData.health
    }

    person: true
}
```




domains/clinic/actions/hand_over.jadpo:

```jadpo
use clinic/entities { Patient, PatientNotFound }
use clinic/types { ClinicalNote, HandoverSummary }
use clinic/failures { SummaryUnavailable }
use clinic/prompts { SummariseNotes }

/// Summarises a patient's notes for the clinician taking over.
action hand_over(
    patient_id: Patient.id
) fails PatientNotFound, SummaryUnavailable -> HandoverSummary {
    var patient: Patient = attempt Patient.get(patient_id)
    var handover_notes: ClinicalNote = patient.notes
    return attempt ai.generate(
        SummariseNotes {
            notes: handover_notes
        },
        as: HandoverSummary
    ) {
        refused: SummaryUnavailable
        malformed: SummaryUnavailable
        timed_out: SummaryUnavailable
        over_budget: SummaryUnavailable
        too_long: SummaryUnavailable
    }
}
```

```text
error: `Patient.notes` reaches a model, and `ai:` doesn't allow `health` data
 --> domains/clinic/actions/hand_over.jadpo:14:20
   |
14 |             notes: handover_notes
   |                    ^^^^^^^^^^^^^^ holds `Patient.notes`
  reason: `SummariseNotes`'s `{notes}` is built from `Patient.notes`, marked `personal: PersonalData.health`, a sensitive category. Each personal-data category sent to a model is listed in `ai: { personal_data: { allowed: } }`, so what the provider is given is decided in `app.jadpo`, where a reviewer sees it.
  next: List `PersonalData.health` in `ai: { personal_data: { allowed: } }`, or leave `Patient.notes` out of `SummariseNotes`'s `{notes}` (human)
  rule: semantic.ai_personal_data_not_allowed
  help: https://jadpo.dev/docs/errors/semantic.ai_personal_data_not_allowed

check failed: 1 error, 8 files
```

`(human)` at the end of the `next:` line tells your coding agent to stop
and ask you which fix you want, because the choice is yours to make: it
decides whether the model's provider is given patients' health records.

## How to fix it

The question is whether the provider may be given this kind of data.

**If it may**, list the category in `app.jadpo`:

```jadpo
            allowed: [PersonalData.identifying, PersonalData.health]
```










The handover summary now sends each patient's notes to the model, and
`app.jadpo` says so where a reviewer reads it. Any other prompt that
sends `health` data is allowed too, since the list is for the whole app.

If it may not, build the prompt only from fields whose categories are
listed, and leave `Patient.notes` out of it. The NHS number is never
sent either way, since its field is marked `to_models: false`.

## Related

- [Personal data sent to a model](/docs/safety-and-privacy.md#personal-data-sent-to-a-model)
- [Following personal data](/docs/following-personal-data.md)
- [Marking personal fields](/docs/marking-personal-fields.md)
- [`semantic.ai_field_refused`](/docs/errors/semantic.ai_field_refused.md)
