§4 Policy

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

On this page

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#

TypeScript
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#

TokenMeaningRuntime obligation
personalActor-private data or effectRestrict to the Principal's own scope
brainShared project contextRequire project membership; project_id MUST be present
localA local workspace directoryBind 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:

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" } }
  }
}