The Windows lab: setup, then the denied delete

One recording from a Windows 11 machine. Claude Code and OpenAI Codex are installed, pointed at the Intercis proxy, and told to delete a folder. Both are denied.

We never took a still from the recording, so nothing on this page is a frame of it. What the page has instead is the rule that matched, printed in full further down, and this drawing of what the denial does to a reply. The two rows we did photograph are on the Linux lab page.

Where the delete is removed Two boxes, one above the other. The first is a reply of this shape as it leaves the provider: a text block holding the model's message, and a tool_use block holding a recursive forced Remove-Item. An arrow runs down to the second box, labelled: a rule matches, policy win-remove-item-recursive-force, verdict deny. The second box is what the agent runtime receives: the same text block, now holding the three lines the proxy writes in place of the call, which read "Intercis blocked this action", then "Policy: win-remove-item-recursive-force", then "This tool call was denied by your organisation's AI governance policy and has been logged for audit review". Under that block is a dashed empty slot where the tool_use block was. A reply of this shape, leaving the provider text the model's message tool_use Remove-Item -Recurse -Force a rule matches win-remove-item-recursive-force verdict deny What the agent runtime receives text Intercis blocked this action. Policy: win-remove-item-recursive-force This tool call was denied by your organisation's AI governance policy and has been logged for audit review. no tool_use block
The proxy takes the tool call out of the reply and puts a plain text block in its place. That block names the policy, which is why the lower box prints it. The runtime reads a message with no tool call in it, so there is no command for it to run. The lower box is the three lines _make_blocked_response returns in apps/proxy/main.py, read on 12 September 2026. The drawing wraps them to fit the box, and it leaves out the stop symbol the first line opens with. The upper box is not a capture of anything. We drew it to show the shape a reply with a tool call in it takes, so the lower box has something to sit against.

Claude Code and Codex on one Windows 11 box, under one policy

1:50. It starts at installation, so you see everything that changes on the machine.

  1. Both agents are installed from their vendors' installers. Nothing of ours goes on the machine.

  2. Each one's base URL is pointed at the proxy, and each is told to delete a folder.

  3. The PowerShell rule below matches both, and the rows arrive in the feed on screen.

Recording intercis-demo-windows-2026-07.mp4 Machine Windows 11 Agents Claude Code, OpenAI Codex Captured July 2026 Length 1:50
A 1080p desktop capture on a machine we control. The still before it starts is a title card we drew, not a frame of the file. There is no caption track and no transcript, so the numbered account under it is the text version of this recording, and it is the one to read if you are not going to press play.

What happens, in order

  1. Both agents are installed from their vendors' own installers. Nothing about Intercis is installed alongside them.

  2. Each agent's base URL is pointed at the proxy, and each sends the key we issued in a header. That is the whole integration, and it is the same two changes for both vendors.

  3. Each agent is told to delete a folder. Each model answers with a tool call carrying the delete, and each answer comes back through the proxy: Claude Code off the Anthropic messages route, Codex off an OpenAI route.

  4. Both are denied. On the PowerShell side the rule that matches is the recursive forced remove, and it only fires when both flags are present, so a plain -Recurse is left to the classifier rather than stopped here.

    policy      win-remove-item-recursive-force
    rule        (?:remove-item|\bri\b)\b(?=[^\n]*-recurse)(?=[^\n]*-force)
                apps/proxy/deny_list.py
    verdict     deny
    classifier  not_run         a rule matched, so it was not consulted

    ri is the PowerShell alias for Remove-Item, so the short form is caught by the same rule. The tool_use block is gone by the time the agent runtime reads the message, so neither agent has a command left to run.

  5. Each denial is written to the event log and appears in the feed on screen: the agent, the tool, a short excerpt of the target, the verdict deny and the policy that matched. Every column those rows carry is listed on the demo page.

Three of the PowerShell policies, by name
  • win-remove-item-recursive-force A recursive forced Remove-Item, the rule printed above.
  • win-vssadmin-shadow-delete Deleting shadow copies.
  • win-wevtutil-clear-log Clearing an event log. No exclusion releases this one at any scope.

These are policy names, not database columns. They are written this way in the deny list, read in the repository on 12 September 2026, and they sit in the same file as the shell rules. The repository is not public, so a name here is a thing to hold us to, not a link you can open.

What to notice

  • Enforcement keys on the tool call, not on the model. The two agents are from different vendors and come off different wire routes, and one tenant governs both.
  • Nothing about the setup is Windows-specific. The proxy sits on the API wire, so the operating system under the agent does not change how a call is judged.
  • The rules are the Windows-specific part. PowerShell has its own, three of which are named at the top of this page, and they sit in the same file as the shell rules.
  • Nine Windows policies cannot be switched off. They are named one by one in the deny list: clearing an event log, deleting the USN journal, encoded PowerShell, a download cradle, and five ways of taking credentials, three of them out of LSASS memory, one out of the registry hives and one out of the directory database. No exclusion releases them at any scope, so an operator cannot waive one for a tenant, an agent or a single command. An operator who needs one of them allowed narrows what tools the agent may call instead. Four whole classes are treated the same way on every platform: credential reads, secret stores, log tampering and obfuscated execution.

    The nine, by name
    win-mimikatz-pattern
    credentials out of LSASS memory
    win-comsvcs-lsass-dump
    credentials out of LSASS memory
    win-procdump-lsass
    credentials out of LSASS memory
    win-reg-save-hives
    credentials out of the registry hives
    win-ntds-dump
    credentials out of the directory database
    win-wevtutil-clear-log
    clearing an event log
    win-fsutil-delete-usn
    deleting the USN journal
    win-powershell-encoded
    encoded PowerShell
    win-download-cradle-iex
    a download cradle
  • Everything else can be released, and it expires. An exclusion is scoped to a tenant, an agent, a command fingerprint, a path or a literal substring, and it carries an end date and a written reason. What the rules stop that you meant to run is on the demo page, with the measured figure.

Policy names and rule text read in the repository on 12 September 2026. The repository is not public, so this is our reading of the file and you cannot check it from outside today.

What this recording does not show

  • We wrote the scenario

    Our machine, our agents, our command. It shows the mechanism working from setup to denial. It is not evidence about how often the rules are right, and it is not an attacker trying to get past them. The figures we can defend, with the labels they were measured under, are in the validation report. The one claim you can check without taking our word for it is the hash chain, and the check for it is two published files and one command.

  • The traffic the proxy never sees

    We govern tool calls that cross the Anthropic and OpenAI API wire. Tools the provider runs on its own servers do not cross it, so hosted MCP calls, web search, file search, code interpreter and image generation are neither judged nor logged. The rest of what the proxy does not cover is on the pilot page.

Run it against your own agents

A 90-day pilot starts in observe mode. The call is judged the same way and the row is written with observe in place of deny, so nothing is blocked until you say so.