LeastGrant

Generated from compatibility/copilot.json, the same record leastgrant doctor reads. Last verified 2026-09-01.

all agents

GitHub Copilot CLI

Partial LIVE VERIFIED 1.0.82 win32

the real agent ran with LeastGrant installed and enforcement was observed happening.

How it attaches

A Claude-format hook file at ~/.copilot/hooks/leastgrant.json. Copilot speaks Claude Code's wire format, so the same handler drives both.

Install it with leastgrant install copilot. Configuration is written to ~/.copilot/hooks/leastgrant.json, alongside anything already there — LeastGrant never removes a hook it did not add.

What a verdict does here

The three verdicts do not travel equally well. This is the table that decides whether LeastGrant is a prompt, a veto, or a suggestion on this agent.

verdictlands?what actually happens
allowyesprobe
askdegradesprobeHonoured interactively. A non-interactive run (copilot -p) has nobody to ask and Copilot turns an ask into a deny — its choice, not LeastGrant's, and the safe direction.
denyyesprobe

Interactive and unattended

This agent does not tell the hook which mode it is in, so LeastGrant cannot distinguish an attended session from an unattended one and treats every session as unattended.

When the hook breaks

The question nobody asks until it matters: if LeastGrant crashes, times out, or cannot start, does the tool call still run?

  • On crash — the call is refused. (probe) If the hook errors, Copilot denies the call rather than running it. Discovered the hard way — a broken hook command blocked everything. This note used to open "the only agent here that fails closed", which was true when it was written and stopped being true once Cursor and Antigravity were measured; three of the five shipped adapters now fail closed on crash.
  • On timeout — not established.
  • Can it be made to fail closed? — yes. It is the default and is not optional.

What it can see

A verdict is only worth as much as the set of actions it is asked about. gated means LeastGrant is consulted before the thing happens; seen after means it is told afterwards and can at best withhold the result; not covered means the action happens with LeastGrant never hearing about it.

tool classcoveragedetail
shell commandsgatedprobe
file readsgatedprobe
file writesgatedprobe
deletionsunknownunknown
MCP callsunknownunknown
subagent spawnunknownunknown
network / webunknownunknown

What decides this later

The highest-value write on your machine is not any single tool call. It is the file that settles what the agent may do next time — its hook configuration, its standing permission grants, the servers it is wired to, the memory a later session is handed as context. LeastGrant floors an agent write to every path below, so it always reaches a person, and test/control-files.test.ts reads this same list and fails the build if any of them stops being floored.

The list is longer than the install path on purpose. Walking it across every agent, rather than reading it, turned up three paths that were not floored at all — and the one that mattered most was Antigravity's config.json, which holds that host's own “Always allow” grants and outlives uninstalling LeastGrant entirely.

pathkindwhat it decides
~/.copilot/hooks/leastgrant.jsonhook configthe Claude-format hook file LeastGrant installs, and the whole ~/.copilot/hooks directory it sits in
.github/copilot-instructions.mdinstructionsstanding instructions every session is given
.github/instructionsinstructionsthe same, per path pattern

What has actually been run

Four different things, deliberately not collapsed into one badge. Reproducing an agent's invocation is not running the agent; a passing conformance suite says our side is right and nothing about whether the host ever calls us.

  • Live agent test — Real copilot -p runs with the hook installed at ~/.copilot/hooks/leastgrant.json; all three verdicts honoured, and a hook error observed failing closed. 1.0.82 · win32 · 2026-09-02
  • Real transport probed — Copilot runs hook commands through PowerShell on Windows; the same quoting failure as Codex was observed, there blocking every call rather than none. 1.0.82 · win32 · 2026-09-02
  • Contract read from the shipped build — Claude-format hooks in snake_case with hookSpecificOutput out; confirmed against the installed CLI. 1.0.82 · win32 · 2026-09-02
  • Conformance suite — Driven by test/conformance.test.ts. 1.0.82 · win32 · 2026-09-02

Not exercised on darwin, linux.

What it cannot do

Not a disclaimer. The point of everything above is that this list exists and is specific.

  • No permission mode is sent, so LeastGrant cannot tell an attended run from an unattended one and records observation rather than approval. Copilot therefore learns more slowly, deliberately.
  • Failing closed means a broken or missing LeastGrant blocks all work rather than silently permitting it. Safer, and much louder.
  • Speaks Claude Code's wire format, so it shares that adapter. A divergence upstream would surface as Copilot-shaped bugs in a file named for Claude.
  • This file's unknown fields need a dedicated binary read; the research pass for it did not complete.
  • Verified on Windows only.