SKILL.md with YAML frontmatter, plus optional reference files, assets and
scripts. The agent sees every skill’s name and description up front, and reads
the body only when it decides the skill is relevant.
No other adapter produces a skill decision. A
skills: block on a policy for an
OpenAI Agents or Pydantic AI agent is valid but inert — nothing on those runtimes
maps to a skill key.
How a skill differs from a tool
A tool rule can say refunds up to 500 USD. A skill rule can say which skill, at
which level, with which content — but no argument fence bounds what the text
persuades the model to do next.
Why Hexgate governs skills
- Audit. Every activation is a policy decision under its skill key, so it lands in the audit trail like any tool call — which skill, at which level.
- Kill-switch.
mode: denywithdraws a skill from every caller without a code change or a redeploy. On deepagents this holds for the top-level agent only: a sub-agent reached throughtaskreads skills, and runs its filesystem and shell tools, without a decision, so denytaskas well (see the deepagents limitations). - Approval.
mode: approval_requiredputs a human in front of a skill the same way it does in front of a tool — see approval-required calls.
The three levels
A skill discloses itself in stages, and policy can gate each one separately:
The split exists because running a skill’s script is arbitrary code execution.
“This team may read the payments runbook but may not run its scripts” has to be
expressible, and
via: [instructions, resource] expresses it. See
the skills: block for the grammar.
What is not gated: a skill’s name and description. They sit in the system
prompt before any tool call, so there is nothing to intercept. Denying a skill
hides its contents, not its existence.
Closed-world, and opt-in
- Unlisted means denied. Once a policy declares a
skills:block, a skill it does not list is denied — even under a permissivedefault_policy. A skill library is a directory: dropping a folder into it adds a capability with no code change and no review, so a new skill has to be named before it runs. Closed-world covers the skills the adapter knows about: on deepagents that means the skills present when the agent was wrapped. A skill folder added afterwards is not recognised, and a read of it decides as a plainread_file— see the deepagents limitations. - It is opt-in. An agent whose policy never mentions skills is not skill-gated
at all: skill activations are decided as the ordinary tool calls they are
(
load_skill,read_file, …). The gate engages across the whole agent once any role lists at least one skill (an emptyskills: {}does not count), the same way agent-level enforcement engages.
Drift
A skill is matched by name. Editing an approved skill’sSKILL.md does not
revoke its approval — the next activation reads the new text under the old rule.
The opt-in answer is content pinning:
a constraint on the content_hash every skill decision carries, so a changed body
no longer matches and denies. Pinning covers the SKILL.md body only. Versioning
an agent as a whole — its skills, tools and prompt together — is a separate thing
Hexgate does not do.
Where skills come from
At registration, the adapter records each skill in the agent’s manifest: its name, description and a hash of itsSKILL.md body. On Google ADK it also
records the reference, asset and script files the skill ships; deepagents
discovery reads frontmatter only, so a deepagents skill shows no files. The platform
shows them on the agent’s page, and the first registration generates a
starter skills: block from
them.