Policy handshake
RoadmapThis capability is on the Roadmap; the API shown here is the planned design. It depends on a policy-discovery endpoint on the gateway, which does not exist today.
On first connection, DDK will fetch the policy set in force for your credentials and expose it:
donkey.policies.models_allowed # ["gpt-4o", "claude-sonnet"]
donkey.policies.tools_allowed # [...]
donkey.policies.budget # the same Budget object, now live
donkey.policies.pii.mode # "block" | "mask" | "log"
donkey.policies.content_safety.on # True
donkey.policies.observed_at # when this view was fetchedWhat it enables
Fewer wasted calls. An agent that requests a model outside its allow-list
costs one round-trip and one refusal, every time. With the handshake, the
adapter picks from models_allowed at construction time and the refusal never
happens. Multiply by a few thousand tickets a day.
Better UX. If pii.mode == "mask", the gateway will redact rather than
reject — so your bot can say “some details were redacted” instead of
“request failed.” Same gateway behaviour, a very different experience, and
today the client has no way to know which mode is in force.
Warm start. It also makes budget live rather than last-known-good: a fresh process currently knows nothing about its budget until its first response comes back.
The handshake is advisory
The handshake never makes an access decision. It exists to avoid wasted calls and to improve UX. The gateway still evaluates every request.
If the client’s cached view and the gateway disagree, the gateway wins and the client learns from the refusal. Skipping a gateway call “because the handshake said it’s fine” is client-side enforcement, which is on the will-not-build list.
This is also why observed_at is part of the surface, as it is on the budget
object: a policy view is a snapshot, and code that cannot tell a snapshot from
live state will eventually make a decision it should not have.