Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 30 Oct 2026. What's built · Install 0.1.0
jadpo
Reference: AI

AI

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.

  • 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 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), 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).

Markdown for agents: /docs/following-personal-data.md.Built from Jadpo main at a707efb.