Security & data handling

What the gate sees — and what it sends.

We're building a trust product, so we owe you total clarity about our own data handling — not a privacy policy you can't parse. Here is the whole truth, and you can verify every line of it in the open-source hook.

The common runtime contract supports Codex, Claude Code, Hermes Agent, Gemini CLI, OpenCode, Goose, and other local or remote agents. The hook details below document one concrete adapter; every adapter must preserve the same metadata-only boundary.

With the local SDK and agent hook, the only thing sent to Warm Winter is abstract decision metadata — the category of an action, its stakes, and whether it worked.

Never your code, your commands, your files, or your outputs. That's true in shadow mode and in enforce mode for these local integrations. The gate decision itself has no LLM in it; it's a calibrated-cell lookup.

Hosted gateway — a different boundary

If you point an OpenAI- or Anthropic-compatible client at our hosted gateway, the request body must transit Warm Winter's memory so we can proxy it to the configured upstream model provider, and the response transits back to you. We do not log or persist those prompt or response bodies. Durable records contain only decision coordinates, verdict, selected model, status, token counts, and the outcome label. If no prompt transit is acceptable, use the local SDK or hook instead.

What crosses the wire — local SDK and hook

Two short lists. That's the whole story.

Sent to our servers by the local hook
domain
always the literal string “agent_ops”
decision_type
a category: file_edit · external_read · shell_cmd · git_push · deploy · destructive_cmd
stakes
low · medium · high (derived from the category)
stated_confidence
a fixed number per category, e.g. 0.75
candidate_action
the tool’s name only — e.g. “Bash”, “Edit”
outcome
on completion: one bit — success or failure
Never leaves your machine through the local hook
  • The contents of any file you edit or write
  • The text of any shell command (e.g. the actual `npm run build`)
  • File paths, directory names, or your repo structure
  • URLs you fetch or anything you search for
  • Tool output, logs, stdout, or error messages
  • Environment variables, secrets, or tokens
No hand-waving

Here is one real request, in full.

When your agent runs npm run build, this is the entire body the gate transmits. The command itself is read on your machine to pick the category, then stays there.

POST https://api.warmwinter.io/api/v1/gate/decide

{
  "domain": "agent_ops",
  "decision_type": "shell_cmd",
  "stakes": "medium",
  "stated_confidence": 0.75,
  "candidate_action": "Bash",
  "context": { "tool": "Bash", "mode": "shadow" }
}

// your command — `npm run build` — never appears here.
On your machine only

The sensitive parts never move.

Classification is local

To choose a category, the hook scans the raw command for keywords (git push, rm -rf) right on your machine. That scan reads the command — and only the resulting category, never the command, is sent.

Bookkeeping is hashed

To match a result back to its decision, the hook stores a SHA-1 hash of the call in a local temp file. Even your on-disk state is a hash, not raw input.

Your key stays local

In the Claude Code adapter, the API key lives in local settings. For project scope it is written to a gitignored settings.local.json, so it never lands in version control. Other runtime adapters must provide an equivalent local-secret boundary.

By design

The gate advises. It never sits in your execution path.

  • Shadow mode (the default) emits no decision at all — Claude Code's normal allow/ask flow runs exactly as if the hook weren't there. It only records, so cells calibrate.
  • Enforce mode maps the verdict to Claude Code's own prompt: act → allow, escalate / abstain → ask you. It can ask for a human; it never silently acts for you.
  • It fails open. If the gate is unreachable, it never blocks your work and never rubber-stamps it — shadow stays invisible, enforce defers to you.
The honest caveat

What our servers can still infer.

Even without content, a stream of metadata is still information: over time our servers can see the categories, timing, and success rates of your agent's actions — a shape of your activity, never its substance. We'd rather tell you that plainly than pretend metadata is nothing.

If even that is more than you want to share, you have two outs: point the SDK at your own deployment (set WARMWINTER_BASE_URL) so nothing leaves your infrastructure, or run the hook in local mode. The whole thing is MIT-licensed and self-hostable for exactly this reason.

Your controls

You can verify, scope, or revoke any of it.

Read every line

The hook and SDK are open source (MIT). Nothing about what we send is hidden — it’s a short, plain Python file.

Start in shadow

The default observes only and never blocks. You opt into enforce mode yourself, later, once cells you trust have verified.

Scope it down

Gate a single repo with --scope project, or preview the exact changes first with --dry-run before anything is written.

Revoke anytime

Delete a key with one call (DELETE /api/v1/gate/keys/{id}); uninstall by removing the hook entry from your settings. No lock-in.

Found something, or have a question?

Security questions and responsible-disclosure reports go straight to the founder. We'd rather hear it early than ship a blind spot.