---
title: "§4 Policy"
description: "Normative schema for policy.json (operation, land, confirm), with coverage rules and the semantics runtimes must enforce."
canonical: https://harnesscontextprotocol.io/docs/specification/policy
---

# §4 Policy

> Normative schema for policy.json (operation, land, confirm), with coverage rules and the semantics runtimes must enforce.

The Policy file is `policy.json` at the pack root. It MUST be a JSON object and
is validated strictly: unknown fields at any level MUST fail parse.

## 4.1 Schema

```ts
type Operation = 'read' | 'write'
type Land      = 'personal' | 'brain' | 'local'

type PolicyEntry = {
  operation: Operation
  privacy: { land: Land }
  confirm?: boolean          // writes only
}

type PolicyFile = {
  surface_id: string         // = pack_id
  version: 1
  verbs:    Record<string, PolicyEntry>
  stimuli:  Record<string, PolicyEntry>   // default {}
}
```

## 4.2 Operation

1. `read` denotes a command with no side effect an Invoker would need to undo.
2. `write` denotes a command that changes state.
3. Validating a prospective write MUST be `read`.
4. A dry-run or preview mode of a write MUST remain `write` and MUST NOT persist
   side effects. If persistence cannot be guaranteed the pack MUST NOT offer the
   flag.
5. A command that establishes or refreshes Binding MUST be `write` and is
   additionally gated by `pack.connect` (§9.4).
6. A trigger's `operation` MUST be `read`. Sense cannot write.

## 4.3 Land

| Token | Meaning | Runtime obligation |
|-------|---------|--------------------|
| `personal` | Actor-private data or effect | Restrict to the Principal's own scope |
| `brain` | Shared project context | Require project membership; `project_id` MUST be present |
| `local` | A local workspace directory | Bind to the sandbox working directory. Not a tenant |

1. Runtimes MUST reject a land token other than these three.
2. Runtimes MUST NOT let a command argument select the tenant. Tenant comes from
   the Principal's session (§9.2).
3. Products MAY map `brain` to their own shared-context object. They MUST NOT
   introduce additional land tokens without an RFC.

## 4.4 Coverage

1. Every `verb_key` in the manifest MUST appear in `verbs`.
2. Every key in `verbs` MUST be a `verb_key` in the manifest.
3. Every `ref` in manifest `stimulusTriggers` MUST appear in `stimuli`.
4. Every key in `stimuli` MUST be a declared `ref`.
5. `surface_id` MUST equal the manifest `id`.

Violations are lint issues of kind `missing_verb`, `extra_verb`,
`missing_stimulus`, `extra_stimulus`, and `write_stimulus` (a trigger whose
entry is not `read`, §4.2.6). Runtimes MUST reject a pack with any of them.

## 4.5 Confirm

1. `confirm` MAY be set only on entries with `operation: write`.
2. When `confirm` is `true`, a runtime MUST refuse the command unless the exec
   envelope's `args` contains `confirm: true` or `apply: true` (string `"true"`
   is accepted on the CLI face).
3. The refusal MUST occur before Binding mint and before any Adapter runs, and
   MUST return `error: "confirm required"`.
4. A pack SHOULD mirror `confirm` on the CLI face with a `--confirm` or `--apply`
   flag in the command's `cli[]`.
5. No Invoker MAY bypass the gate. Host approval UIs present the gate and do
   not replace it.

## 4.6 Grants (informative cross-reference)

Policy states effect class; runtime capabilities state who. The mapping is
normative in §9.4:

```text
operation read          → verb.exec.read
operation write         → verb.exec.write
connect command         → pack.connect
trigger delivery        → sense.enable
```

## 4.7 Example (informative)

```json
{
  "surface_id": "mail",
  "version": 1,
  "verbs": {
    "mail.list":    { "operation": "read",  "privacy": { "land": "personal" } },
    "mail.send":    { "operation": "write", "privacy": { "land": "personal" }, "confirm": true },
    "mail.connect": { "operation": "write", "privacy": { "land": "personal" } },
    "notes.create": { "operation": "write", "privacy": { "land": "brain" } }
  },
  "stimuli": {
    "new_item":         { "operation": "read", "privacy": { "land": "personal" } },
    "binding.degraded": { "operation": "read", "privacy": { "land": "personal" } }
  }
}
```

## Sitemap

- [Documentation](https://harnesscontextprotocol.io/docs)
- [Packs](https://harnesscontextprotocol.io/packs)
- [Glossary](https://harnesscontextprotocol.io/docs/reference/glossary)
- [llms.txt](https://harnesscontextprotocol.io/llms.txt)
- [llms-full.txt](https://harnesscontextprotocol.io/llms-full.txt)
- [OpenAPI](https://harnesscontextprotocol.io/openapi.json)
- [MCP](https://harnesscontextprotocol.io/mcp)
