[{"data":1,"prerenderedAt":506},["ShallowReactive",2],{"docs-\u002Fdocs\u002Fv2\u002Ftui\u002Fescalations":3},{"id":4,"title":5,"body":6,"description":498,"extension":499,"meta":500,"navigation":501,"path":502,"seo":503,"stem":504,"__hash__":505},"docs\u002Fdocs\u002Fv2\u002Ftui\u002Fescalations.md","Escalations",{"type":7,"value":8,"toc":489},"minimark",[9,13,22,27,30,35,88,95,98,102,106,109,122,213,224,300,311,326,340,344,347,350,365,374,381,385,392,399,403,418,425,428,432,435,458,462,469,476,485],[10,11,5],"h1",{"id":12},"escalations",[14,15,16,17,21],"p",{},"Some calls should not be a yes or a no decided in advance. An agent searching the web is\nusually fine; an agent searching the web on a machine you share is a decision you want to\nmake when it happens. ",[18,19,20],"strong",{},"Escalation is the third answer"," — pause, ask, continue.",[23,24],"terminal-image",{"alt":25,"src":26},"The terminal paused mid-tool-call, showing search.web with its query and three choices: allow once (just this call), allow always (remember this), and deny (refuse this call)","\u002Ftui\u002Fpolicy-escalation-prompt.webp",[14,28,29],{},"The agent is suspended mid-call. Nothing has run yet, and nothing will until you answer.",[31,32,34],"h2",{"id":33},"three-outcomes","Three outcomes",[36,37,38,50],"table",{},[39,40,41],"thead",{},[42,43,44,47],"tr",{},[45,46],"th",{},[45,48,49],{},"What happens",[51,52,53,64,78],"tbody",{},[42,54,55,61],{},[56,57,58],"td",{},[18,59,60],{},"allow once",[56,62,63],{},"This call proceeds. The next identical call asks again.",[42,65,66,71],{},[56,67,68],{},[18,69,70],{},"allow always",[56,72,73,74,77],{},"This call proceeds, and a ",[18,75,76],{},"grant"," is written so it stops asking.",[42,79,80,85],{},[56,81,82],{},[18,83,84],{},"deny",[56,86,87],{},"The call is refused. The agent is told, and carries on.",[14,89,90,94],{},[91,92,93],"code",{},"Escape"," denies. A policy prompt has no neutral exit — the call is blocked on your answer\neither way, so dismissing it would just mean waiting for a timeout to deny it for you.",[14,96,97],{},"Denial is not a crash. It reaches the agent as an ordinary error naming what was refused,\nand a well-written agent adapts:",[23,99],{"alt":100,"src":101},"A denied tool call rendered as CAPSULE_POLICY_DENIED: search.web denied by policy, with the agent explaining it cannot access live web results and offering to help another way","\u002Ftui\u002Fpolicy-denied.webp",[31,103,105],{"id":104},"where-the-rule-comes-from","Where the rule comes from",[14,107,108],{},"Two files can ask for a prompt, and they answer different questions.",[14,110,111,116,117,121],{},[18,112,113],{},[91,114,115],{},"axon.config.ts"," — what ",[118,119,120],"em",{},"this agent"," needs. The author knows their agent pushes to git\nand wants a human on it:",[123,124,129],"pre",{"className":125,"code":126,"language":127,"meta":128,"style":128},"language-ts shiki shiki-themes dark-plus","\u002F\u002F my-agent\u002Faxon.config.ts\nexport default defineAgent({\n    policy: {\n        process: { allow: [\"git *\"], escalate: [\"git push*\"] },\n    },\n})\n","ts","",[91,130,131,140,158,168,201,207],{"__ignoreMap":128},[132,133,136],"span",{"class":134,"line":135},"line",1,[132,137,139],{"class":138},"sOLPB","\u002F\u002F my-agent\u002Faxon.config.ts\n",[132,141,143,147,150,154],{"class":134,"line":142},2,[132,144,146],{"class":145},"sYbnZ","export",[132,148,149],{"class":145}," default",[132,151,153],{"class":152},"sCudf"," defineAgent",[132,155,157],{"class":156},"sTNBD","({\n",[132,159,161,165],{"class":134,"line":160},3,[132,162,164],{"class":163},"s3F5K","    policy:",[132,166,167],{"class":156}," {\n",[132,169,171,174,177,180,183,187,190,193,195,198],{"class":134,"line":170},4,[132,172,173],{"class":163},"        process:",[132,175,176],{"class":156}," { ",[132,178,179],{"class":163},"allow:",[132,181,182],{"class":156}," [",[132,184,186],{"class":185},"sKc5r","\"git *\"",[132,188,189],{"class":156},"], ",[132,191,192],{"class":163},"escalate:",[132,194,182],{"class":156},[132,196,197],{"class":185},"\"git push*\"",[132,199,200],{"class":156},"] },\n",[132,202,204],{"class":134,"line":203},5,[132,205,206],{"class":156},"    },\n",[132,208,210],{"class":134,"line":209},6,[132,211,212],{"class":156},"})\n",[14,214,215,116,220,223],{},[18,216,217],{},[91,218,219],{},"profile.config.ts",[118,221,222],{},"you"," allow on this machine, across every agent, including\nones you installed and never read:",[123,225,227],{"className":125,"code":226,"language":127,"meta":128,"style":128},"\u002F\u002F profile.config.ts\nexport default defineProfile({\n    policy: {\n        tools:   { search: \"escalate\" },\n        process: { run: \"escalate\", spawn: false },\n    },\n})\n",[91,228,229,234,245,251,268,291,295],{"__ignoreMap":128},[132,230,231],{"class":134,"line":135},[132,232,233],{"class":138},"\u002F\u002F profile.config.ts\n",[132,235,236,238,240,243],{"class":134,"line":142},[132,237,146],{"class":145},[132,239,149],{"class":145},[132,241,242],{"class":152}," defineProfile",[132,244,157],{"class":156},[132,246,247,249],{"class":134,"line":160},[132,248,164],{"class":163},[132,250,167],{"class":156},[132,252,253,256,259,262,265],{"class":134,"line":170},[132,254,255],{"class":163},"        tools:",[132,257,258],{"class":156},"   { ",[132,260,261],{"class":163},"search:",[132,263,264],{"class":185}," \"escalate\"",[132,266,267],{"class":156}," },\n",[132,269,270,272,274,277,279,282,285,289],{"class":134,"line":203},[132,271,173],{"class":163},[132,273,176],{"class":156},[132,275,276],{"class":163},"run:",[132,278,264],{"class":185},[132,280,281],{"class":156},", ",[132,283,284],{"class":163},"spawn:",[132,286,288],{"class":287},"scz_3"," false",[132,290,267],{"class":156},[132,292,293],{"class":134,"line":209},[132,294,206],{"class":156},[132,296,298],{"class":134,"line":297},7,[132,299,212],{"class":156},[14,301,302,303,306,307,310],{},"The profile is a ",[18,304,305],{},"ceiling",". An agent can narrow within it and can never widen past it, so\n",[91,308,309],{},"search: \"escalate\""," above means every agent asks — whatever its own config says. The\nstricter of the two layers wins on every call.",[14,312,313,314,317,318,321,322,325],{},"That is the division worth internalising: ",[18,315,316],{},"the agent's config is a statement about the\nagent, the profile's is a statement about your machine."," \"This agent only reads ",[91,319,320],{},".\u002Fsrc","\"\nbelongs to the author. \"Nothing on my laptop touches ",[91,323,324],{},"~\u002F.ssh","\" belongs to you, because it\ncannot depend on every agent author agreeing with you forever.",[14,327,328,329,334,335,339],{},"See ",[330,331,333],"a",{"href":332},"\u002Fdocs\u002Fv2\u002Fagent\u002Fpolicy","policy"," and\n",[330,336,338],{"href":337},"\u002Fdocs\u002Fv2\u002Ftui\u002Fstructure\u002Fpolicy","profile policy"," for the full field reference.",[31,341,343],{"id":342},"what-allow-always-actually-writes","What \"allow always\" actually writes",[14,345,346],{},"A grant — recorded in your profile, not in either config file.",[14,348,349],{},"That placement is deliberate. Editing a config you authored from a palette keypress is\ninvasive, and an agent-level grant could not widen a profile that escalated anyway, so\n\"always\" would fail confusingly in exactly the case that produced the prompt.",[14,351,352,353,356,357,360,361,364],{},"A grant is keyed to ",[18,354,355],{},"the agent and the exact subject you were asked about",", never widened\ninto a pattern. Approving ",[91,358,359],{},"git push origin main"," does not silently become ",[91,362,363],{},"git push *"," —\nif you want that, write it in your config, where it is a decision you made rather than one\ninferred from a single yes.",[14,366,367,370,371,373],{},[18,368,369],{},"A grant can only ever satisfy an escalation."," It can never overturn a ",[91,372,84],{}," from either\nlayer. \"Stop asking me this\" and \"override the rule I set\" are different acts, and\ncollapsing them would let one keypress undo a machine-wide rule you set deliberately.",[14,375,376,377,380],{},"Grants live in ",[91,378,379],{},"~\u002F.axon\u002Fprofiles\u002F\u003Cyou>\u002Fstore\u002Fgrants.jsonl",", and revocation appends rather\nthan rewrites — a decision made and later withdrawn is two facts, not zero. The file is the\naudit trail.",[31,382,384],{"id":383},"more-than-one-at-a-time","More than one at a time",[14,386,387,388,391],{},"Escalations ",[18,389,390],{},"queue",". Two overlapping wakes can both raise one, and neither may be\ndropped: a dropped escalation is a denial you never saw, on a call you might well have\nallowed.",[14,393,394,395,398],{},"They are answered oldest first — the agent blocked longest is the one closest to timing out\ninside its capsule. And a request's clock ",[18,396,397],{},"starts when it is shown to you",", not when it\nwas raised, so the ones waiting behind the current prompt are not burning their deadline\nwhile you read.",[31,400,402],{"id":401},"when-nobody-is-watching","When nobody is watching",[14,404,405,406,409,410,413,414,417],{},"Headless — ",[91,407,408],{},"axon run",", cron, CI, a route handler — there is no surface to ask. Escalations\n",[18,411,412],{},"fail closed"," after the capsule's timeout, 30 seconds by default and configurable via\n",[91,415,416],{},"resources.escalationTimeoutMs",".",[14,419,420,421,424],{},"They are recorded as ",[18,422,423],{},"expired rather than denied",", which is a real distinction: nothing\nrefused the call, nobody was there. The record survives, so approving the request later\nwrites a grant that the next attempt reads.",[14,426,427],{},"The practical consequence: an agent you intend to run unattended should not depend on\nescalation. Decide those rules in config, where they hold with nobody present.",[31,429,431],{"id":430},"seeing-what-happened","Seeing what happened",[14,433,434],{},"Every escalation is recorded — including ones you answered instantly — which is what makes\n\"three escalations this session, two approved\" answerable after the fact.",[14,436,437,438,441,442,445,446,449,450,453,454,417],{},"In a conversation the decision shows inline: ",[91,439,440],{},"capsule:escalating"," while it waits,\n",[91,443,444],{},"capsule:denied"," if refused. ",[91,447,448],{},":open log"," puts the full event stream in your editor, and\n",[91,451,452],{},":open flame"," shows where the pause sat in the run. See\n",[330,455,457],{"href":456},"\u002Fdocs\u002Fv2\u002Fapi\u002Fevents","events",[31,459,461],{"id":460},"see-also","See also",[14,463,464,468],{},[18,465,466],{},[330,467,333],{"href":332}," — the agent's own block, and every rule shape.",[14,470,471,475],{},[18,472,473],{},[330,474,338],{"href":337}," — the machine-wide ceiling.",[14,477,478,484],{},[18,479,480],{},[330,481,483],{"href":482},"\u002Fdocs\u002Fv2\u002Fconcepts\u002Fkernel-and-policy","Kernel & Policy"," — how enforcement works, and why\na denied call never reaches the function body.",[486,487,488],"style",{},"html pre.shiki code .sOLPB, html code.shiki .sOLPB{--shiki-default:#6A9955}html pre.shiki code .sYbnZ, html code.shiki .sYbnZ{--shiki-default:#C586C0}html pre.shiki code .sCudf, html code.shiki .sCudf{--shiki-default:#DCDCAA}html pre.shiki code .sTNBD, html code.shiki .sTNBD{--shiki-default:#D4D4D4}html pre.shiki code .s3F5K, html code.shiki .s3F5K{--shiki-default:#9CDCFE}html pre.shiki code .sKc5r, html code.shiki .sKc5r{--shiki-default:#CE9178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .scz_3, html code.shiki .scz_3{--shiki-default:#569CD6}",{"title":128,"searchDepth":142,"depth":142,"links":490},[491,492,493,494,495,496,497],{"id":33,"depth":142,"text":34},{"id":104,"depth":142,"text":105},{"id":342,"depth":142,"text":343},{"id":383,"depth":142,"text":384},{"id":401,"depth":142,"text":402},{"id":430,"depth":142,"text":431},{"id":460,"depth":142,"text":461},"Some calls should not be a yes or a no decided in advance. An agent searching the web is\nusually fine; an agent searching the web on a machine you share is a decision you want to\nmake when it happens. Escalation is the third answer — pause, ask, continue.","md",{},true,"\u002Fdocs\u002Fv2\u002Ftui\u002Fescalations",{"title":5,"description":498},"docs\u002Fv2\u002Ftui\u002Fescalations","9cUVrr4iOqPfeShqR-C_Zw76pXglO_rbsBtQgbwTcG8",1786914042758]