Kai Ase Siren
Skip to content

Body projection and pinned values

How an inline grant shapes the body it sends: map renames caller input, set pins what the caller may not touch, and the two combine.

map projects caller input

map "commonAnnotations.summary" to="text" projects required nested string inputs onto fresh top-level keys, forwards nothing else, and resolves to strings only. It cannot combine with body fields, a caller-named key and a mapped one both coming from the model, so which wins at a shared name has no single reading.

Renaming exists because an upstream's required parameter may collide with a reserved engine flag such as query. Mapping it is the only way to expose it under a name the caller can state.

set pins what the caller cannot

set k=v states a scalar, all a KDL property holds. set { ... } carries a shape: one node per key, one argument, several for an array, or a block for an object, nesting as deep as needed.

set numResults=5 { contents { text #true }; categories "news" "papers" }

A pinned key never enters the input schema, so the model can neither name nor vary it. That is what separates a pin from a field, and it matters most where a parameter drives cost. A key given twice, one with no value, one carrying both a value and a block, and key=value inside the block each have no single reading and fail closed.

The two together

A pin seeds the projected body, so a grant needing both a renamed input and a fixed upstream parameter states each with the node built for it:

can search result {
    path "/search"
    body { map "search_text" to="query" }
    set { contents { text #true } }
}

One key cannot be both pinned and mapped, which fails closed rather than picking a silent winner. Absence remains the stronger control where the wanted value is already the upstream default. A pin is for the value that is not.

Alone on a leaf that declares no body fields, set owns the body outright, which is the state-toggle shape: the caller's body is discarded rather than merged.

set beside declared body fields

A leaf may declare body fields and pin others. The caller fills the declared fields, those are validated as usual, and the pins are laid over the result, the same precedence a mapped body gets. So a grant can expose the inputs a model needs while fixing an argument the model must not reach.

The pinned name goes undeclared. It never enters the input schema, so a caller cannot supply it and the pin has nothing to win against.

can create record {
    path "/table/{tableId}/record"
    body {
        field "fieldKeyType" type="string"
        array "records" raw=true required=true
    }
    set typecast=#false
}

A set value is a KDL keyword, so it is #false and #true. Bare false lexes as an identifier and fails closed with invalid identifier: "false".

Before this, declaring both silently discarded every declared field at request time: the pin replaced the whole body and the caller's input never left the process. Nothing warned, because the guardfile parsed clean.

What the command line cannot do

A mapped source mounts no CLI flag, so umbra refuses a mapped-body grant rather than sending a body missing its mapped keys. Those grants are reached through the MCP surface, which carries nested inputs.