A friendly, example-first guide to gating tool calls on their arguments.
Allowing a tool is often too blunt. You don’t want the agent to make any
refund — you want refunds under $500. You don’t want it to write any
file — only files under /srv/. That “only when…” is a condition.A condition is a yes/no test on the arguments of the call. Attach conditions to
a tool and it runs only when all of them say yes:
tools: refund: mode: allow constraints: - args.amount <= 500 # only refunds up to $500 - args.currency == "USD" # …and only in USD
That’s the whole idea. The rest of this page shows how to say more.
Conditions read the call’s arguments under args. — args.amount,
args.currency, args.file_path.
Every line must pass. Listing two conditions means both have to hold.
When in doubt, it’s a no. If an argument is missing or the wrong type, the
condition fails and the call is denied. Safe by default — you never have to
write “…and the value exists.”
The operators are what you’d expect: ==, !=, <, <=, >, >=.Comparing to text? Quote it — double quotes:
- args.currency == "USD"
Quotes matter. args.currency == USD (no quotes) doesn’t compare to the word
“USD” — it compares args.currency to another field called USD, which
almost never exists, so the call is denied. If you mean text, quote it.
matches uses a regular expression and is unanchored — it looks for the
pattern anywhere in the string. Add ^ and $ when you mean the whole value,
like the ticket-ID example above.
When an argument is a list, every and any let you constrain its
elements. Inside, . is “the current element”:
tools: send_email: mode: allow constraints: - count(args.to) <= 5 # at most 5 recipients - every(args.to, endswith(., "@acme.com")) # all on the company domain
every(list, …) — the condition must hold for all elements.
any(list, …) — it must hold for at least one.
count(list) … — compares the number of elements.
If the elements are objects, reach into them with .field:
Change the number in one place and every rule that uses it follows. It also lets
someone tune the allowlist without touching the logic. Put shared constants in a
mixin (inherits:) so several roles can reuse them.
Everything above judges one call in isolation. run.* judges the invocation
so far, which is how you stop an agent stuck in a loop rather than one asking
for something it shouldn’t:
default_policy: mode: allow constraints: - run.tool_calls < 20 # at most 20 tools per invocation - run.elapsed_seconds < 300 # at most 5 minutes - run.errors < 5 # give up after 5 failures
Put these on default_policy and they apply to every tool that falls through to
it. The counters only ever go up within a run, so once a cap trips it stays
tripped — a circuit breaker, not a gate that flaps.Test one at its threshold without running an agent:
The constraints reference lists all 13
paths and the handful of places the count can lag reality.To cap the agent across runs instead, use
agent_usage.*, and dry-run it the
same way with --agent-usage:
Missing or wrong-typed arguments deny. A numeric rule like
args.amount <= 500 won’t be fooled by a string arriving in args.amount —
it fails closed.
Dev and production agree. The same conditions are enforced identically in
local development and in a compiled, signed policy bundle — there’s one
grammar, checked both ways.
Not yet supported:and/or/notinside a quantifier body (e.g.
every(args.x, .a == 1 or .b == 2)), and in against another field.
Constraints reference — the full operator,
function, and quantifier tables in one place.
Define policy in code — build the same conditions in
Python with typed constructors, and unit-test them.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"hexgate","colors":{"primary":"#3B82F6","light":"#60A5FA","dark":"#2563EB"},"logo":{"light":"https://mintcdn.com/hexamind/Sz1fI7dVJWhG1jGp/logo/light.svg?fit=max\u0026auto=format\u0026n=Sz1fI7dVJWhG1jGp\u0026q=85\u0026s=d7f949cb2f7b21bccfd23b147449f5be","dark":"https://mintcdn.com/hexamind/Sz1fI7dVJWhG1jGp/logo/dark.svg?fit=max\u0026auto=format\u0026n=Sz1fI7dVJWhG1jGp\u0026q=85\u0026s=70d4bcb78fb97c51abfd772727ad7754","href":"https://hexgate.ai"},"favicon":"https://mintcdn.com/hexamind/Sz1fI7dVJWhG1jGp/favicon.svg?fit=max\u0026auto=format\u0026n=Sz1fI7dVJWhG1jGp\u0026q=85\u0026s=48420d1d8ce58db050d2be4216c69c36","navbar":{"links":[{"href":"https://github.com/HexamindOrganisation/hexgate","label":"GitHub"}],"primary":{"type":"button","label":"Get started","href":"/quickstart"}},"footer":{"socials":{"github":"https://github.com/HexamindOrganisation/hexgate"}},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"PyPI","icon":"cube","href":"https://pypi.org/project/hexgate/"},{"anchor":"Discussions","icon":"github","href":"https://github.com/HexamindOrganisation/hexgate/discussions"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"hexamind","hasAudioNarration":false,"actualSubdomain":"hexamind","customDomains":["docs.hexgate.ai"],"gitSource":{"type":"github","owner":"hexamindorganisation","repo":"hexgate","deployBranch":"main","contentDirectory":"docs","isPrivate":false,"mountPath":"","label":""},"chroma":{"collectionId":"d9b65f34-06b4-4288-b97d-6d969298c000","liveDeploymentHistoryId":"6adb625eadb57cc3ba9018fb","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6adb625eadb57cc3ba9018fb"},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6adb625eadb57cc3ba9018fb","clientVersion":"0.0.3965","searchFilterCounts":[{"language":"default","tag":"Using Hexgate","count":33},{"language":"default","tag":"Concepts","count":13},{"language":"default","tag":"Platform","count":12},{"language":"default","tag":"Policy","count":7},{"language":"default","tag":"Framework adapters","count":5},{"language":"default","tag":"CLI","count":4},{"language":"default","tag":"Get started","count":4},{"language":"default","tag":"Self-hosting","count":4},{"language":"default","tag":"Reference","count":4},{"language":"default","tag":"Internals","count":3}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"policy/writing-conditions","slug":"/policy/writing-conditions","pageMetadata":{"title":"Writing conditions","description":"A friendly, example-first guide to gating tool calls on their arguments.","href":"/policy/writing-conditions"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"A friendly, example-first guide to gating tool calls on their arguments.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={a:`a`,code:`code`,em:`em`,li:`li`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Note,Tip,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Note)_missingMdxReference(`Note`,true);if(!Tip)_missingMdxReference(`Tip`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`Allowing a tool is often too blunt. You don’t want the agent to make `,_jsx(_components.em,{children:`any`}),`\nrefund — you want refunds `,_jsx(_components.strong,{children:`under $500`}),`. You don’t want it to write `,_jsx(_components.em,{children:`any`}),`\nfile — only files `,_jsxs(_components.strong,{children:[`under `,_jsx(_components.code,{children:`/srv/`})]}),`. That “only when…” is a `,_jsx(_components.strong,{children:`condition`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`A condition is a yes/no test on the arguments of the call. Attach conditions to\na tool and it runs only when `,_jsx(_components.strong,{children:`all`}),` of them say yes:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`tools`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` refund`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= 500`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # only refunds up to $500`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.currency == \"USD\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # …and only in USD`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`That’s the whole idea. The rest of this page shows how to say more.`}),`\n`,_jsx(Heading,{level:`2`,id:`three-things-to-keep-in-mind`,children:`Three things to keep in mind`}),`\n`,_jsx(Note,{children:_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Conditions read the call’s arguments`}),` under `,_jsx(_components.code,{children:`args.`}),` — `,_jsx(_components.code,{children:`args.amount`}),`,\n`,_jsx(_components.code,{children:`args.currency`}),`, `,_jsx(_components.code,{children:`args.file_path`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Every line must pass.`}),` Listing two conditions means `,_jsx(_components.em,{children:`both`}),` have to hold.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`When in doubt, it’s a no.`}),` If an argument is missing or the wrong type, the\ncondition fails and the call is denied. Safe by default — you never have to\nwrite “…and the value exists.”`]}),`\n`]})}),`\n`,_jsx(Heading,{level:`2`,id:`your-first-condition`,children:`Your first condition`}),`\n`,_jsx(_components.p,{children:`Compare an argument to a value:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= 500`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The operators are what you’d expect: `,_jsx(_components.code,{children:`==`}),`, `,_jsx(_components.code,{children:`!=`}),`, `,_jsx(_components.code,{children:`\u003c`}),`, `,_jsx(_components.code,{children:`\u003c=`}),`, `,_jsx(_components.code,{children:`>`}),`, `,_jsx(_components.code,{children:`>=`}),`.`]}),`\n`,_jsxs(_components.p,{children:[`Comparing to text? `,_jsx(_components.strong,{children:`Quote it`}),` — double quotes:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.currency == \"USD\"`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[`Quotes matter. `,_jsx(_components.code,{children:`args.currency == USD`}),` (no quotes) doesn’t compare to the `,_jsx(_components.em,{children:`word`}),`\n“USD” — it compares `,_jsx(_components.code,{children:`args.currency`}),` to `,_jsx(_components.strong,{children:`another field`}),` called `,_jsx(_components.code,{children:`USD`}),`, which\nalmost never exists, so the call is denied. If you mean text, quote it.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`one-of-a-set`,children:`One of a set`}),`\n`,_jsxs(_components.p,{children:[`Use `,_jsx(_components.code,{children:`in`}),` (and `,_jsx(_components.code,{children:`not in`}),`) to check membership:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.currency in [\"USD\", \"EUR\", \"GBP\"]`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.priority not in [\"urgent\", \"critical\"]`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`combining-conditions`,children:`Combining conditions`}),`\n`,_jsxs(_components.p,{children:[`Separate lines are already `,_jsx(_components.strong,{children:`and`}),` — all must hold. When you need `,_jsx(_components.strong,{children:`or`}),`, or to\ngroup things, write it inline with `,_jsx(_components.code,{children:`and`}),` / `,_jsx(_components.code,{children:`or`}),` / `,_jsx(_components.code,{children:`not`}),` and parentheses:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`3`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`3`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= 100 or role == \"admin\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`not (args.env == \"prod\" and args.force == false)`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.code,{children:`or`}),` binds loosest, then `,_jsx(_components.code,{children:`and`}),`, then `,_jsx(_components.code,{children:`not`}),` — the usual precedence. Reach for\nparentheses whenever it makes the intent clearer.`]}),`\n`,_jsx(Heading,{level:`2`,id:`checking-the-shape-of-text`,children:`Checking the shape of text`}),`\n`,_jsx(_components.p,{children:`For strings, four helpers go beyond exact match:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`4`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`4`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`startswith(args.file_path, \"/srv/\")`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`endswith(args.file_path, \".md\")`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`contains(args.subject, \"urgent\")`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`matches(args.ticket_id, \"^INC-[0-9]+$\")`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # a regular expression`})]}),`\n`]})})}),`\n`,_jsx(Tip,{children:_jsxs(_components.p,{children:[_jsx(_components.code,{children:`matches`}),` uses a regular expression and is `,_jsx(_components.strong,{children:`unanchored`}),` — it looks for the\npattern anywhere in the string. Add `,_jsx(_components.code,{children:`^`}),` and `,_jsx(_components.code,{children:`$`}),` when you mean the `,_jsx(_components.em,{children:`whole`}),` value,\nlike the ticket-ID example above.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`rules-over-a-list`,children:`Rules over a list`}),`\n`,_jsxs(_components.p,{children:[`When an argument is a `,_jsx(_components.strong,{children:`list`}),`, `,_jsx(_components.code,{children:`every`}),` and `,_jsx(_components.code,{children:`any`}),` let you constrain its\nelements. Inside, `,_jsx(_components.code,{children:`.`}),` is “the current element”:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`tools`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` send_email`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`count(args.to) \u003c= 5`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # at most 5 recipients`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`every(args.to, endswith(., \"@acme.com\"))`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # all on the company domain`})]}),`\n`]})})}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`every(list, …)`}),` — the condition must hold for `,_jsx(_components.strong,{children:`all`}),` elements.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`any(list, …)`}),` — it must hold for `,_jsx(_components.strong,{children:`at least one`}),`.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.code,{children:`count(list) …`}),` — compares the number of elements.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`If the elements are objects, reach into them with `,_jsx(_components.code,{children:`.field`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`every(args.line_items, .price \u003c= 1000)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`any(args.reviewers, .role == \"senior\")`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`comparing-two-arguments`,children:`Comparing two arguments`}),`\n`,_jsx(_components.p,{children:`The right-hand side can be another argument, not just a fixed value:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= args.limit`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # never refund more than the caller's own limit`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.start \u003c args.end`})]}),`\n`]})})}),`\n`,_jsxs(Heading,{level:`2`,id:`reusing-values-with-consts`,children:[`Reusing values with `,_jsx(_components.code,{children:`consts`})]}),`\n`,_jsxs(_components.p,{children:[`When the same value shows up in several rules, name it once in a `,_jsx(_components.code,{children:`consts:`}),` block\nand reference it as `,_jsx(_components.code,{children:`consts.\u003cname>`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`7`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`7`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`consts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` max_refund`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`500`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` managed_repos`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"hexgate\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"hexkit\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"hexgate-landing\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`tools`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` refund`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"args.amount \u003c= consts.max_refund\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] }`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` create_pr`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: { `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"args.repo in consts.managed_repos\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`] }`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Change the number in one place and every rule that uses it follows. It also lets\nsomeone tune the allowlist without touching the logic. Put shared constants in a\nmixin (`,_jsx(_components.code,{children:`inherits:`}),`) so several roles can reuse them.`]}),`\n`,_jsx(Heading,{level:`2`,id:`who’s-calling-and-what-they’re-calling`,children:`Who’s calling, and what they’re calling`}),`\n`,_jsx(_components.p,{children:`Two facts about the call itself are always available:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`role == \"admin\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # the caller's role`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`tool == \"refund_order\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # the tool being invoked`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`They’re most useful with `,_jsx(_components.code,{children:`or`}),` — “under the limit, `,_jsx(_components.strong,{children:`or`}),` an admin”:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`- `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= consts.max_refund or role == \"admin\"`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`stopping-a-run-that’s-gone-wrong`,children:`Stopping a run that’s gone wrong`}),`\n`,_jsxs(_components.p,{children:[`Everything above judges one call in isolation. `,_jsx(_components.code,{children:`run.*`}),` judges the `,_jsx(_components.strong,{children:`invocation\nso far`}),`, which is how you stop an agent stuck in a loop rather than one asking\nfor something it shouldn’t:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`6`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`6`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`default_policy`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`run.tool_calls \u003c 20`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # at most 20 tools per invocation`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`run.elapsed_seconds \u003c 300`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # at most 5 minutes`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`run.errors \u003c 5`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # give up after 5 failures`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`Put these on `,_jsx(_components.code,{children:`default_policy`}),` and they apply to every tool that falls through to\nit. The counters only ever go up within a run, so once a cap trips it stays\ntripped — a circuit breaker, not a gate that flaps.`]}),`\n`,_jsx(_components.p,{children:`Test one at its threshold without running an agent:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`hexgate`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` policy`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` test`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` policy.yaml`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --role`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` default`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --tool`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` search`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --run-facts`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"tool_calls\": 20}'`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The `,_jsx(_components.a,{href:`/policy/constraints#run-facts-run`,children:`constraints reference`}),` lists all 13\npaths and the handful of places the count can lag reality.`]}),`\n`,_jsxs(_components.p,{children:[`To cap the agent across runs instead, use\n`,_jsx(_components.a,{href:`/policy/constraints#agent-usage-agent_usage`,children:_jsx(_components.code,{children:`agent_usage.*`})}),`, and dry-run it the\nsame way with `,_jsx(_components.code,{children:`--agent-usage`}),`:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`hexgate`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` policy`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` test`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` policy.yaml`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --role`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` default`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --tool`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` agent.run`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --args`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"agent\": \"support\"}'`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --agent-usage`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` '{\"invocations_1h\": 100}'`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`a-worked-example`,children:`A worked example`}),`\n`,_jsx(_components.p,{children:`A support agent that can email customers and issue refunds, with a stricter\ndefault role and a looser billing role:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`26`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`26`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`version`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`1`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`consts`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` max_refund`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#B5CEA8`},children:`500`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` support_domains`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: [`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"acme.com\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`, `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"example.org\"`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`]`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`roles`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` default`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` tools`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` send_email`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`count(args.to) \u003c= 10`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`every(args.to, endswith(., \"@acme.com\"))`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` refund`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`approval_required`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= args.order_total`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # never more than the order`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= consts.max_refund or role == \"billing\"`})]}),`\n`,_jsx(_components.span,{className:`line`}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` billing`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` tools`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` refund`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` mode`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`allow`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` constraints`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`args.amount \u003c= args.order_total`})]}),`\n`]})})}),`\n`,_jsx(Heading,{level:`2`,id:`good-to-know`,children:`Good to know`}),`\n`,_jsx(Note,{children:_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Missing or wrong-typed arguments deny.`}),` A numeric rule like\n`,_jsx(_components.code,{children:`args.amount \u003c= 500`}),` won’t be fooled by a string arriving in `,_jsx(_components.code,{children:`args.amount`}),` —\nit fails closed.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Dev and production agree.`}),` The same conditions are enforced identically in\nlocal development and in a compiled, signed policy bundle — there’s one\ngrammar, checked both ways.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Not yet supported:`}),` `,_jsx(_components.code,{children:`and`}),`/`,_jsx(_components.code,{children:`or`}),`/`,_jsx(_components.code,{children:`not`}),` `,_jsx(_components.em,{children:`inside`}),` a quantifier body (e.g.\n`,_jsx(_components.code,{children:`every(args.x, .a == 1 or .b == 2)`}),`), and `,_jsx(_components.code,{children:`in`}),` against another field.`]}),`\n`]})}),`\n`,_jsx(Heading,{level:`2`,id:`where-to-next`,children:`Where to next`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.a,{href:`/policy/constraints`,children:`Constraints reference`})}),` — the full operator,\nfunction, and quantifier tables in one place.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:_jsx(_components.a,{href:`/policy/in-code`,children:`Define policy in code`})}),` — build the same conditions in\nPython with typed constructors, and unit-test them.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Writing conditions","description":"A friendly, example-first guide to gating tool calls on their arguments.","href":"/policy/writing-conditions"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Three things to keep in mind","slug":"three-things-to-keep-in-mind","depth":2,"children":[]},{"title":"Your first condition","slug":"your-first-condition","depth":2,"children":[]},{"title":"One of a set","slug":"one-of-a-set","depth":2,"children":[]},{"title":"Combining conditions","slug":"combining-conditions","depth":2,"children":[]},{"title":"Checking the shape of text","slug":"checking-the-shape-of-text","depth":2,"children":[]},{"title":"Rules over a list","slug":"rules-over-a-list","depth":2,"children":[]},{"title":"Comparing two arguments","slug":"comparing-two-arguments","depth":2,"children":[]},{"title":"Reusing values with consts","slug":"reusing-values-with-consts","depth":2,"children":[]},{"title":"Who’s calling, and what they’re calling","slug":"who’s-calling-and-what-they’re-calling","depth":2,"children":[]},{"title":"Stopping a run that’s gone wrong","slug":"stopping-a-run-that’s-gone-wrong","depth":2,"children":[]},{"title":"A worked example","slug":"a-worked-example","depth":2,"children":[]},{"title":"Good to know","slug":"good-to-know","depth":2,"children":[]},{"title":"Where to next","slug":"where-to-next","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"hexamind","siteName":"hexgate","title":"Writing conditions - hexgate","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-09T13:41:57.514Z","originalFileLocation":"policy/writing-conditions.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"A friendly, example-first guide to gating tool calls on their arguments.\">\u003cmeta data-mint-head name=\"application-name\" content=\"hexgate\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Writing conditions - hexgate\">\u003cmeta data-mint-head property=\"og:description\" content=\"A friendly, example-first guide to gating tool calls on their arguments.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"hexgate\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.hexgate.ai/policy/writing-conditions\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://hexamind.mintlify.app/_mintlify/api/og/v2?division=Policy\u0026amp;title=Writing+conditions\u0026amp;description=A+friendly%2C+example-first+guide+to+gating+tool+calls+on+their+arguments.\u0026amp;theme=4192cabb10185815ede9237a\u0026amp;signature=2bf1fde57c67541887816560c70b1230f5ce662d5c426efec2013c7a06ef0287\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Writing conditions - hexgate\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"A friendly, example-first guide to gating tool calls on their arguments.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://hexamind.mintlify.app/_mintlify/api/og/v2?division=Policy\u0026amp;title=Writing+conditions\u0026amp;description=A+friendly%2C+example-first+guide+to+gating+tool+calls+on+their+arguments.\u0026amp;theme=4192cabb10185815ede9237a\u0026amp;signature=2bf1fde57c67541887816560c70b1230f5ce662d5c426efec2013c7a06ef0287\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/hexamind/W3iZq8x_Zqjvq4qm/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"hexgate\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#3B82F6\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.hexgate.ai/policy/writing-conditions\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/policy/writing-conditions.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.hexgate.ai/#organization\",\"name\":\"hexgate\",\"url\":\"https://docs.hexgate.ai\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/hexamind/Sz1fI7dVJWhG1jGp/logo/light.svg?fit=max\u0026auto=format\u0026n=Sz1fI7dVJWhG1jGp\u0026q=85\u0026s=d7f949cb2f7b21bccfd23b147449f5be\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.hexgate.ai#website\",\"name\":\"hexgate\",\"url\":\"https://docs.hexgate.ai\",\"publisher\":{\"@id\":\"https://docs.hexgate.ai/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.hexgate.ai/policy/writing-conditions#webpage\",\"url\":\"https://docs.hexgate.ai/policy/writing-conditions\",\"name\":\"Writing conditions\",\"description\":\"A friendly, example-first guide to gating tool calls on their arguments.\",\"dateModified\":\"2026-10-09T13:41:57.514Z\",\"isPartOf\":{\"@id\":\"https://docs.hexgate.ai#website\"},\"breadcrumb\":{\"@id\":\"https://docs.hexgate.ai/policy/writing-conditions#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.hexgate.ai/policy/writing-conditions#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Policy\",\"item\":\"https://docs.hexgate.ai/policy/yaml-shape\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Writing conditions\",\"item\":\"https://docs.hexgate.ai/policy/writing-conditions\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://docs.hexgate.ai/policy/writing-conditions#article\",\"headline\":\"Writing conditions\",\"name\":\"Writing conditions\",\"description\":\"A friendly, example-first guide to gating tool calls on their arguments.\",\"url\":\"https://docs.hexgate.ai/policy/writing-conditions\",\"mainEntityOfPage\":{\"@id\":\"https://docs.hexgate.ai/policy/writing-conditions#webpage\"},\"dateModified\":\"2026-10-09T13:41:57.514Z\",\"publisher\":{\"@id\":\"https://docs.hexgate.ai/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.hexgate.ai#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"hexgate\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"hexgate","nav":{"global":{"anchors":[{"anchor":"PyPI","icon":"cube","href":"https://pypi.org/project/hexgate/"},{"anchor":"Discussions","icon":"github","href":"https://github.com/HexamindOrganisation/hexgate/discussions"}]},"tabs":[{"tab":"Using Hexgate","groups":[{"group":"Get started","pages":[{"title":"Introduction","href":"/introduction"},{"title":"Quickstart","href":"/quickstart"},{"title":"Which path do I pick?","href":"/two-paths"},{"title":"Build an agent","href":"/guides/build-an-agent"}]},{"group":"Concepts","pages":[{"title":"Policy decision","href":"/concepts/policy-decision"},{"title":"Guards","href":"/concepts/guards"},{"title":"Request context","href":"/concepts/user-scope"},{"title":"Agent-level enforcement","href":"/concepts/agent-level-enforcement"},{"title":"Agent skills","href":"/concepts/skills"},{"title":"Signed policy bundles","href":"/concepts/signed-bundles"},{"title":"Audit trail","href":"/concepts/audit-trail"},{"title":"MCP servers (proxy)","href":"/concepts/mcp"},{"title":"Approval-required","href":"/concepts/approval-required"},{"title":"Approval in other frameworks","href":"/concepts/approval-frameworks-compared"},{"title":"Bans","href":"/concepts/bans"},{"title":"Workspace sandbox","href":"/concepts/sandbox"},{"title":"Network egress","href":"/concepts/egress"}]},{"group":"Framework adapters","pages":[{"title":"Adapters overview","href":"/adapters/overview"},{"title":"OpenAI Agents SDK","href":"/adapters/openai"},{"title":"LangChain / LangGraph","href":"/adapters/langchain"},{"title":"Google ADK","href":"/adapters/google-adk"},{"title":"Pydantic AI","href":"/adapters/pydantic-ai"}]},{"group":"Policy","pages":[{"title":"Policy YAML shape","description":"version, constraints, default_policy, tools, modes.","href":"/policy/yaml-shape"},{"title":"Writing conditions","href":"/policy/writing-conditions"},{"title":"Constraints reference","description":"Every operator, function, and quantifier the condition grammar accepts.","href":"/policy/constraints"},{"title":"Define policy in code","href":"/policy/in-code"},{"title":"WASM bundles","href":"/policy/wasm-bundles"},{"title":"Signing \u0026 verification","href":"/policy/signing"},{"title":"Local override (HEXGATE_LOCAL_POLICY)","href":"/policy/local-override"}]},{"group":"CLI","pages":[{"title":"hexgate chat","href":"/cli/chat"},{"title":"hexgate serve","href":"/cli/serve"},{"title":"hexgate register","href":"/cli/register"},{"title":"hexgate policy","href":"/cli/policy"}]}]},{"tab":"Platform","pages":[{"title":"Platform","href":"/platform/overview"}]},{"tab":"Reference","pages":[{"title":"Reference","href":"/sdk"}]},{"tab":"Internals","pages":[{"title":"Internals","href":"/internals/audit-pipeline"}]}]},"title":"Writing conditions - hexgate","buildId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","deploymentId":"dpl_849ArpqvBiCczQiT1Y1stNGpbqHT","dynamics":[],"chunks":[]}