Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 5 Nov 2026. What's built · Install 0.3.0
jadpo
ReferenceAI

Built-in servicesAIDetails

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: personal:, on an entity's, an event's or an email's field or an object's, input's or output's a package declares, is one of the fourteen categories, and to_models:, on an entity's or an event's, 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;
    • a library's function, whose result may hold anything it was given, in any part;
    • 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.

The approval report flags a sensitive category in its difference of the personal-data report.

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