Agents
GitHub Copilot (VS Code agent mode / CLI)
GitHub Copilot (VS Code agent mode / CLI) and chock: install methods and steps, what it can enforce, and the evidence behind it.
Install methods: sync. Agentseam tier block+rewrite, grade best-effort before a tool runs.
Install methods
- Repo hooks:
chock sync --repo . --agents copilotwrites.github/hooks/*.json(ask the user before running it)
What it can enforce
- Tier
- block+rewrite
- Grade before a tool runs
- best-effort
- Fail mode before a tool runs
- open
- Basis
- live-run-partial
- Recorded
- 2026-09-28
Events
| Event | Can block | Can rewrite | Fail mode |
|---|---|---|---|
pre_tool | yes | yes | open |
post_tool | yes | no | open |
prompt_submit | yes | no | open |
session_start | no | no | open |
subagent_start | no | no | open |
stop | yes | no | open |
subagent_stop | yes | no | open |
Ask support
Answers an ask with: ask. Honours ask: yes. Evidence: tested (tests/test_guard_fail_to_ask.py::test_a_crashed_guard_asks_rather_than_allowing).
Hook timeout
The engine records no timeout for this agent.
Test status
- Repo hooks: tested. A test of the plugin says nothing about repo hooks.
- Through the sync install, at hook point agent-hooks: Copilot CLI and VS Code agent mode, 2026-08-23. live probe: an exit-2 deny blocked a matched command on both (chock 5d78831)
Known limits
Two products behind one row, and they do not spell events the same way: HOOKS_BY_TARGET gives VS Code agent mode PascalCase names (Claude Code's exactly) and the GitHub Copilot CLI camelCase ones (sessionStart, userPromptSubmitted, agentStop). This adapter claimed camelCase only until 2026-08-28, so it never claimed a real VS Code payload at all -- those went to claude_code alone and were answered in its dialect, which is right at PreToolUse and wrong everywhere else. timestamp, which chatHookService merges into every payload, is what separates the two; Tabnine sends it too, so SessionStart -- the one event name Tabnine and VS Code share -- is left ambiguous rather than guessed. postToolUseFailure, previously mapped, claimed and installed for, is in neither vendor's name map: it never existed. The hook file install writes is the object keyed by event that both products document for .github/hooks/*.json, and VS Code's own schema tolerates the _agentseam marker (microsoft/vscode@d93a384 hookSchema.ts: additionalProperties true on the file, the hooks map and each command; read 2026-10-13); whether the Copilot CLI tolerates it, or a file with no version, its docs do not say and its source is not public. Four response dialects, because the consumer reads a different shape at each: PreToolUse takes hookSpecificOutput.permissionDecision (ask and updatedInput both native, and updatedInput is validated against the tool's schema and silently discarded if it fails), UserPromptSubmit and PostToolUse take a top-level {decision: block, reason}, Stop and SubagentStop take those two fields nested in hookSpecificOutput and drop the block if the reason is missing, and SessionStart/SubagentStart run under ignoreErrors:true where even exit 2 is swallowed. hookEventName is echoed rather than hardcoded: _toHookResult strips hookSpecificOutput outright when the name does not match the event being run. Fails OPEN, not closed as this row claimed for two weeks: exit 2 blocks, but any other non-zero exit is a NonBlockingError that warns the user and lets the call proceed. Also parses Claude settings.json via hookClaudeCompat, and ignores matcher -- it is read and thrown away, so there is no tool filtering and the guard must check event.tool itself. Memory writes arrive as the 'memory' tool (create/str_replace/insert), not file edits. Copilot CLI's own camelCase preToolUse (docs.github.com/en/copilot/reference/hooks-configuration, read 2026-09-27; vendor docs, not yet witnessed live) sends no event name at all -- {sessionId, timestamp, cwd, toolName, toolArgs} -- so it is claimed by toolArgs and answered with a top-level {permissionDecision, permissionDecisionReason}; it has no input rewrite, so a transform there blocks. Live, Windows, 2026-09-28 (Copilot CLI runtime, one observation): a pre_tool hook whose command errored under PowerShell (the entry then had no powershell key) made Copilot deny EVERY tool call ("Denied by preToolUse hook ... (hook errored)"). That is not recorded as fail_mode closed: it is a single uncontrolled run of one runtime, the error was a shell parse failure rather than a hook that started and exited with a chosen non-2 code, and it contradicts the VS Code source reading (any non-zero exit other than 2 is a NonBlockingError) that the open claim rests on. Both may be true -- the CLI runtime and VS Code's own engine may differ -- but until a hook that runs and exits 1 is tried on each, open stays and a consumer must not rely on either behaviour. Which of the two products a Windows payload came from is not reliably visible in the payload. The camelCase agentStop payload names no event, so it is claimed by stopReason and parsed as a stop.
Built from engine 5a4b6287a46e and catalog 1e60d211c1bb.