# Following personal data

The full rules for how the compiler follows personal data to a model.
The common case is under
[Personal data sent to a model](safety-and-privacy.md#personal-data-sent-to-a-model).

- **`personal_data: { allowed: }`** lists `PersonalData.<category>`
  values, each once. Left out, it allows none, so an app that sends
  personal data has to say so. Anything else in it is
  `ai.settings_invalid`.
- **The marks** are read where
  [Marking personal fields](marking-personal-fields.md)
  puts them, on an entity's and an event's fields: `personal:` is one of
  the fourteen categories, and `to_models:` is a `Bool`, each
  `type.setting_value` otherwise. A field of a standard type that is
  personal data whatever holds it is that category too, as well as its
  own mark.
- **What reaches a model** is each field of a `Prompt` an action or
  function builds, whichever call takes it. It is also the text
  `ai.embed` and `ai.embed_all` send, since an embedding model is sent
  the text as a prompt's model is.
- **The flow** is the one policy follows to check who may see a field
  ([Field restrictions](field-restrictions.md)), run again in
  its own mode. It goes through:
  - variables and assignments;
  - your app's functions and actions, a parameter that reaches a model
    being checked where it is passed, in the caller's terms;
  - standard operations, each carrying its arguments;
  - lists, maps and objects, and a batch's items;
  - events: a subscriber's part of its event is checked against what
    every `emit` of it put there and the event's own marks.

  Where policy takes a query's `Output` or a map layer as proved where
  it is declared, this check follows it to the fields the query reads. A
  marked field read from a value the check can't follow to a record or a
  parameter counts as that field.
- **A placeholder's own type** counts too. Whatever it holds, however
  deep (an object's fields, a list's items), is sent whatever fills it.
  So a prompt with a `List<ChatMessage>` sends `health`, even built with
  `[]`.
- **What decided a value** is sent with it, counted as policy counts it,
  so a `match` on a marked field sends what that field holds. Only what a
  loop goes through (a `for`'s list, `list.map`'s and `list.count`'s) is
  left out, except for what decided which items it has. Otherwise a loop
  over records would send each record's every field.
- **One problem per value and holder.** A `to_models: false` field is
  `semantic.ai_field_refused`, whatever its categories. When a marked
  field is of a standard type that is personal data, the type is named
  with the field. Each problem names the field (`Patient.notes`) or the
  type (a `NhsNumber`) and the category, never a value. Listing a
  category is a privacy decision, so
  `semantic.ai_personal_data_not_allowed`'s next step is marked
  `(human)`: your agent asks you before it lists one.
- **Checked only when `ai:` is written,** since without it nothing
  reaches a model (an `ai` call is then `ai.connection_required`). Like
  policy's check, it runs once policy reads cleanly.

Flagging a sensitive category in the approval report isn't built yet
([What is built](ai-built.md)).
