The validating, credential-injecting request pipeline: match -> policy -> validate -> credentials -> execute -> normalize.
Requests come from the sandbox as JSON-shaped maps (string keys). Errors
return %{phase: atom, message: String.t()} — phase-tagged so tool-layer
error messages can say what failed without leaking internals.
Error messages crossing back to the sandbox are fixed strings wherever the
underlying detail could embed a credential (transport failures, resolver
reasons). The detail goes to Logger instead.