---
title: "Reviewed changes"
description: "Widening what sandboxes may reach waits for a tenant admin, a governance change says why and may wait for a second admin, and an agent's file changes are approved as a diff before they land."
canonical_url: "https://docs.oz0.ai/govern/reviewed-changes"
---
# Reviewed changes

> Widening what sandboxes may reach waits for a tenant admin, a governance change says why and may wait for a second admin, and an agent's file changes are approved as a diff before they land.

For: tenant admins and governance reviewers.

Review the proposed change, its reason and what access it widens before approving it. Governance changes, plugin configurations and code changesets have different reviewers and checks; follow the page for the kind of change in front of you.

These kinds of change go past a person before they take effect:

- A widening of what the tenant's sandboxes may reach. A new entry in the tenant's egress list, or a plugin whose egress the tenant does not permit yet, waits as a **change request** until a tenant admin approves the delta they saw.
- A loosening of a governance setting, with four eyes on. A shorter retention, a lifted legal hold, a released kill switch, the AI label off and the rest [below](https://docs.oz0.ai/govern/reviewed-changes#four-eyes-for-governance-changes) wait for another admin.
- A credential binding, under `second_admin`. [Below](https://docs.oz0.ai/govern/reviewed-changes/plugin-configurations#credential-bindings).
- A plugin update from new hands. An update whose version comes from another publisher, repository owner or custody epoch, or that follows a moved listing, waits as a change request of kind `plugin_custody` that shows who the plugin came from and who it would come from ([updates from new hands](https://docs.oz0.ai/build/plugins/install/update#updates-from-new-hands)).
- A command rule from an approval card. An allow of a command written from its approval card, where four eyes is on, and either rule proposed by someone who decides approvals but may not change the tool policy, wait as a change request of kind `command_rule` until a tenant admin approves it ([allowlist a command from its card](https://docs.oz0.ai/govern/command-rules/allow-from-card#allowlist-a-command-from-its-card)). Each proposal waits on its own, by its rule's ID; the approval applies it to the policy as it is then, as the approver, keeping who proposed it and why.
- A file-writing agent's changes. An agent that declares `changes:` works on a copy and ends with a **changeset**: the diff of its work directory, which a person, or the agent's own policy, approves before the function the agent names applies it, for example as a draft pull request.
- An agent's change to a plugin's tests or rules. A changeset, a skill proposal or a push of changes that touches a plugin's evals, its agents' outcome checks, its policy files, CODEOWNERS or CI workflows needs a second approval by another person with the governance permission, [below](https://docs.oz0.ai/govern/reviewed-changes/protected-paths#protected-paths): no agent, key or policy gives it.

Both are in the audit trail, both are bound to exactly what was shown, and both are on the **Approvals** page.

## Change requests

The platform compares the list as it would be with the list as it is, entry by entry. The comparison is exact: it either says what the new list allows that the old one refused, or says that it cannot decide, which counts as a widening. It never guesses. It cannot decide when only DNS could (a deny entry for an address), or when the lists are too large to compare within its bounds; a plugin or an agent may name at most 200 egress entries, as a tenant's own list may. What it finds, per entry:

<table>
<thead>
  <tr>
    <th>
      Finding
    </th>
    
    <th>
      What it means
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        host
      </code>
    </td>
    
    <td>
      A host, or a port of a host, the list did not allow
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        wildcard
      </code>
    </td>
    
    <td>
      A new wildcard, or one that matches more names than before (<code>
        *.example.com
      </code>
      
       after <code>
        *.api.example.com
      </code>
      
      )
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        internal
      </code>
    </td>
    
    <td>
      An address of the node, its network or a cloud metadata service, such as <code>
        169.254.169.254
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ip_literal
      </code>
    </td>
    
    <td>
      An IP address, reached without a name the proxy can check
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        raw_tcp
      </code>
    </td>
    
    <td>
      Raw TCP (an entry ending in <code>
        /tcp
      </code>
      
      ) where only TLS was allowed
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        deny_removed
      </code>
    </td>
    
    <td>
      A deny entry is gone, and something it refused is allowed again
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        credentialed_host
      </code>
    </td>
    
    <td>
      The entry reaches a host with a credential bound to it
    </td>
  </tr>
</tbody>
</table>

Hosts that serve files anyone can publish. When an entry that widens reaches a content host (a code host's raw files, archives or gists such as `raw.githubusercontent.com`, a package registry such as `registry.npmjs.org` or `pypi.org`, a container registry, a model hub, an object store, a paste site, a tunnel or a file share), its finding says so, with the reason: whatever anyone publishes there, a session that may reach the host may download and run.

A pattern that overlaps one counts too (`*.githubusercontent.com`, `*.amazonaws.com`).

The note is a reason to look, not a verdict. It is never a finding of its own: a content host the tenant permits already is no widening, nothing is refused for being one, who must approve does not change, and approving the change applies it as any other.

A package registry or a plugin's own download host is often exactly what a tenant needs.

The same note shows on a plugin configuration's egress line, in `oz0 egress learn`, on the install screen and, before you save, under **Govern › Policy › Egress**; plugin lint warns about a plugin's own ([OZ-S022](https://docs.oz0.ai/build/plugins/structure/lint-rules#oz-s022)).

The tool policy's lint (`oz0 policy lint`) checks tool rules and never sees an egress list, so it does not say it.

A change with no finding (a narrowing, or something the tenant permits already) applies at once. One with findings waits:

```bash [Terminal]
$ oz0 tenant egress acme api.github.com pypi.org
Change request cr-3f2a91c0-7b1d: egress_tenant of acme, pending
  requested by user:ann just now
  + pypi.org
What it widens:
  host  pypi.org  pypi.org:80  a host or port the list did not allow; content host pypi.org: this host serves files anyone can publish: allowing it lets an agent download and run them
A content-host note is a reason to look, not a verdict: nothing is refused for it, and approving the change still applies it.
Delta sha256:9c1f... (review-widening confirm)
Approve it with: oz0 change approve cr-3f2a91c0-7b1d --tenant acme --delta sha256:9c1f...
Nothing changed yet: the change waits for a tenant admin's approval.

$ oz0 change list --tenant acme
$ oz0 change show cr-3f2a91c0-7b1d --tenant acme
$ oz0 change approve cr-3f2a91c0-7b1d --tenant acme       # shows it, then approves that delta
$ oz0 change reject cr-3f2a91c0-7b1d --tenant acme --note "use the mirror"
```

An approval names the delta's digest (`--delta`, which `change approve` fills in from what it just showed): one whose delta is another is refused, so a yes counts only for what was shown. A request whose list changed meanwhile (another change applied first) fails when it is approved instead of overwriting the newer list; ask again. A new request for the same list or plugin supersedes the one that waited.

**A plugin install or update** whose plugin or agents list hosts the tenant does not permit yet waits the same way: `plugin install` says so and installs nothing, and the approval installs it, with the request as it was made. What the tenant permits is its own list and every installed plugin's and agent's egress, so an update with the same egress, or a plugin that asks for a host another plugin has, installs at once.

`oz0 egress learn <job> --apply` asks for the tenant's list with the entries a job's denials suggest (never an internal address), as a change request.

A [credential binding](https://docs.oz0.ai/admin/credential-injection) widens no egress; it applies at once in a `confirm` tenant and waits for another admin under `second_admin` ([below](https://docs.oz0.ai/govern/reviewed-changes/plugin-configurations#credential-bindings)); a widening that would reach a host a credential is bound to shows it as a `credentialed_host` finding.

`--approve` on `tenant egress` and `egress learn --apply`, and `--approve-egress` on `plugin install` and `plugin update`, approve the request at once after printing its delta, when you may. In `oz0 dev`, the dev tenant approves the working copy's egress itself and says so.

### Who approves

A tenant admin, never an API key. The tenant's `review-widening` setting says whether the admin who asked may:

```bash [Terminal]
oz0 tenant review-widening acme              # show it
oz0 tenant review-widening acme second_admin # another admin than the requester approves
```

<table>
<thead>
  <tr>
    <th>
      Setting
    </th>
    
    <th>
      Who approves
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        confirm
      </code>
      
       (the default)
    </td>
    
    <td>
      Any admin of the tenant, the requester too, after seeing the delta
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        second_admin
      </code>
    </td>
    
    <td>
      An admin other than the requester
    </td>
  </tr>
</tbody>
</table>

Regulated tenants should use `second_admin`. Turning it on takes an admin; relaxing it back to `confirm` takes an owner, so one admin cannot turn the second pair of eyes off and approve alone. With `second_admin`, a tenant with a single admin cannot widen until a second admin (or a cluster admin) approves.

A plugin install's request names the commit (or the bundle's or image's digest) its source resolved to, and that is part of the delta's digest. If the source moved before the approval (a branch got a new commit) or the egress changed, the approval fails and installs nothing; the admin who asked installs again, which files a new request in their own name.

Applying an approval never files a request in the approver's name, so under `second_admin` the person who asked can never approve what only they have seen. A plugin the install brings in that widens egress of its own waits for its own request, filed in the requester's name.

In the console, **Approvals → Changes** lists the requests for admins, those asked for in the [period](https://docs.oz0.ai/getting-started/web-ui/navigation#periods-filters-and-pages) you pick (the last 30 days unless you pick another) and filtered by state (waiting, applied, rejected or failed; every state when none is chosen), with the entries added and removed, each finding and what to weigh, and **Approve** or **Reject**.

The audit trail has `egress.change_requested`, `egress.change_approved`, `egress.change_rejected` and `egress.change_applied`, each with the lists before and after, and `tenant.review_widening`.

## Four eyes for governance changes

Every change of a governance setting says why: `--reason` on the command (at most 500 characters; a script may set `OZ0_REASON` once), a **Why** field in the console, and the `reason` field in the admin API. `--decision-ref` (at most 200 characters) names the decision or case it follows, such as a case number under your archive rules. The audit entry keeps both with the setting's name. The governance settings:

<table>
<thead>
  <tr>
    <th>
      Setting
    </th>
    
    <th>
      What loosens it
    </th>
    
    <th>
      Where
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        retention
      </code>
    </td>
    
    <td>
      a shorter retention, or one where everything was kept
    </td>
    
    <td>
      <code>
        oz0 retention set
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        legal_hold
      </code>
    </td>
    
    <td>
      lifting the hold
    </td>
    
    <td>
      <code>
        oz0 retention release
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        kill_switch
      </code>
    </td>
    
    <td>
      releasing a switch (a cancel switch never goes back to park)
    </td>
    
    <td>
      <code>
        oz0 kill release
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        risk_class
      </code>
    </td>
    
    <td>
      a lower risk class in the inventory
    </td>
    
    <td>
      <code>
        oz0 inventory set --risk
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        data_rules
      </code>
    </td>
    
    <td>
      a region added, every region allowed, providers that keep data allowed; a rule by level removed or widened
    </td>
    
    <td>
      <code>
        oz0 model rules
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        ai_label
      </code>
    </td>
    
    <td>
      turning the AI label off
    </td>
    
    <td>
      <code>
        oz0 tenant ai-label set --off
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        tool_policy
      </code>
    </td>
    
    <td>
      <a href="#tool-policy-loosenings">
        Details
      </a>
    </td>
    
    <td>
      <a href="#tool-policy-loosenings">
        Details
      </a>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        review_widening
      </code>
    </td>
    
    <td>
      <code>
        second_admin
      </code>
      
       back to <code>
        confirm
      </code>
    </td>
    
    <td>
      <code>
        oz0 tenant review-widening
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        egress
      </code>
    </td>
    
    <td>
      a widening, which its own change request reviews (above)
    </td>
    
    <td>
      <code>
        oz0 tenant egress
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sandbox_isolation
      </code>
    </td>
    
    <td>
      a requirement dropped
    </td>
    
    <td>
      <code>
        oz0 tenant sandbox-isolation
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        remote_sandbox
      </code>
    </td>
    
    <td>
      remote sandboxes allowed
    </td>
    
    <td>
      <code>
        oz0 tenant remote-sandbox
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        works_council
      </code>
    </td>
    
    <td>
      the mode off, or a lower threshold
    </td>
    
    <td>
      <code>
        oz0 tenant works-council
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        notify_content
      </code>
    </td>
    
    <td>
      notifications that carry the call's arguments
    </td>
    
    <td>
      <code>
        oz0 tenant notify-content
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        cors_origins
      </code>
    </td>
    
    <td>
      an origin added
    </td>
    
    <td>
      <code>
        oz0 tenant cors
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        four_eyes
      </code>
    </td>
    
    <td>
      four eyes off
    </td>
    
    <td>
      <code>
        oz0 tenant four-eyes
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        erasure_policy
      </code>
    </td>
    
    <td>
      every change but <code>
        allowed
      </code>
      
       to <code>
        second-person
      </code>
      
      : one admin erasing alone again, or erasure turned off or on (<a href="https://docs.oz0.ai/govern/personal-data/erase#the-erasure-policy">
        the erasure policy
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 tenant erasure-policy
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        keep_for
      </code>
    </td>
    
    <td>
      an agent's keep-for period shortened or cleared
    </td>
    
    <td>
      <code>
        oz0 retention keep-for
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        legal_basis
      </code>
    </td>
    
    <td>
      an agent's own legal basis changed or removed (setting one tightens)
    </td>
    
    <td>
      <code>
        oz0 inventory legal-basis
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        purpose_bases
      </code>
    </td>
    
    <td>
      a purpose's legal basis changed or removed, or a new description of a basis a purpose or an agent names (setting one tightens)
    </td>
    
    <td>
      <code>
        oz0 inventory purposes set
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        vulnerable_installs
      </code>
    </td>
    
    <td>
      refusing fewer installs with <a href="https://docs.oz0.ai/build/plugins/vulnerabilities#installs">
        known vulnerabilities
      </a>
      
      : off, or <code>
        critical
      </code>
      
       after <code>
        high
      </code>
    </td>
    
    <td>
      <code>
        oz0 tenant vulnerable-installs
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        delegated_tokens_off_cluster
      </code>
    </td>
    
    <td>
      letting <a href="https://docs.oz0.ai/concepts/delegation-and-identity#workload-or-delegated">
        delegated identity tokens
      </a>
      
      , which name the person a job runs for, go to services outside the cluster
    </td>
    
    <td>
      <code>
        oz0 tenant oidc delegated-off-cluster
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mcp_clients
      </code>
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/build/apps/mcp-server/oauth#who-may-connect">
        MCP clients
      </a>
      
       on loopback addresses let in, or a client host, client ID or redirect scheme allowed
    </td>
    
    <td>
      <code>
        oz0 mcp clients policy
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        label_policies
      </code>
    </td>
    
    <td>
      an agent's clearance raised, widened, removed or newly set by the tenant (it replaces the definition's), a wall removed, a person listed for fewer compartments or removed, a host added to the egress list in force at any level or a list removed (<a href="https://docs.oz0.ai/govern/taint-and-labels/label-policies#label-policies">
        label policies
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 tenant labels clearance|walls|people|egress
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        notify_decide_keys
      </code>
    </td>
    
    <td>
      a notification rule's webhook that names the API key its receiver decides with (<code>
        --decide-key
      </code>
      
      ): a key named, the key sent other approvals (a changed event or filter), its webhook moved, or such a rule turned on (<a href="https://docs.oz0.ai/agents/approvals/configure#keys-that-decide">
        keys that decide
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 notify rule put
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        guardrails_classified_local
      </code>
    </td>
    
    <td>
      <code>
        GUARDRAILS_CLASSIFIED_LOCAL
      </code>
      
       allows a classification marking anew for agents whose data stays on the node (<a href="https://docs.oz0.ai/build/plugins/verified/guardrails/classified-text#classified-text">
        classified text
      </a>
      
      ); taking one back, or deleting the setting, applies at once
    </td>
    
    <td>
      <code>
        oz0 setting set
      </code>
      
       and <code>
        oz0 setting delete
      </code>
      
       with <code>
        --reason
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        orphan_pause
      </code>
    </td>
    
    <td>
      <a href="https://docs.oz0.ai/spend/budgets-and-quotas#teams-that-nobody-answers-for">
        orphaned teams' routines
      </a>
      
       no longer pause, or pause later
    </td>
    
    <td>
      <code>
        oz0 tenant orphan-pause
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        memory
      </code>
    </td>
    
    <td>
      a later default or longest end for plugins' records, a higher cap per scope, or a new compatible pair of purposes (<a href="https://docs.oz0.ai/build/plugins/verified/memory#safe-by-default">
        memory
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 memory settings set
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        memory_person
      </code>
    </td>
    
    <td>
      memory about people turned on for an agent and a purpose, or shared with another agent or scope; in works-council mode it always waits for another admin (<a href="https://docs.oz0.ai/govern/personal-data/plugin-records#memory-about-people">
        memory about people
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 memory person
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        model_vetting
      </code>
    </td>
    
    <td>
      a model vetted, a local model or one behind an endpoint of the tenant's own, so its jobs no longer start tainted or need sandbox tier 1; or vetted again for other weights, by name or for another endpoint. An approval applies it to the digest and the endpoint the request named, and fails when the provider record calls another since. Removing a vetting applies at once (<a href="https://docs.oz0.ai/spend/models-and-keys/data-rules#provenance-and-vetting">
        provenance and vetting
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 model vet
      </code>
      
      , <code>
        oz0 model unvet
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mail_domains
      </code>
    </td>
    
    <td>
      a mail domain added: agents' mail may go to more addresses (<a href="https://docs.oz0.ai/build/plugins/verified/email#the-tenants-mail-domains">
        ai.oz0/email
      </a>
      
      )
    </td>
    
    <td>
      <code>
        oz0 tenant mail-domains add
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        mail_outside
      </code>
    </td>
    
    <td>
      agents' mail allowed to any domain, not only the tenant's mail domains
    </td>
    
    <td>
      <code>
        oz0 tenant mail-outside
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        sandbox_optout
      </code>
    </td>
    
    <td>
      one named node allowed to run shell and write harness sessions without the tier-1 sandbox (<a href="https://docs.oz0.ai/fleet/nodes#the-sandbox-opt-out">
        the sandbox opt-out
      </a>
      
      ); ending it tightens
    </td>
    
    <td>
      <code>
        oz0 node sandbox-optout
      </code>
    </td>
  </tr>
</tbody>
</table>

### Tool policy loosenings

#### What loosens it

A tool-policy change loosens the policy when it does any of the following:

- Removes or relaxes a rule, makes it shadow-only, or ends it sooner.
- Changes a match or condition.
- Changes a preset so a rule becomes, or stops being, a floor or the origin-default rule.
- Adds an Allow rule, or an Ask or Allow rule where a class refuses. Rules precede classes, so `*=approve` over `destructive: refuse` loosens.
- Turns off the escalation ladder.
- Newly names an API key, team or person in an approve rule's deciders, including floors and origin or sequence rules (`decided-by=key:<id>`; see [keys that decide](https://docs.oz0.ai/agents/approvals/configure#keys-that-decide)).
- Lengthens the tenant's or a rule's approval deadline, letting approvals wait longer before denial.
- Removes four eyes (`not-starter`) from a rule.
- Adds an approve rule that waits longer than the tenant's previous deadline, or puts one before an existing approve rule that waits longer, lets the starter approve or names different deciders. The first matching rule decides, so the new rule takes those calls from it.

A shorter deadline and added four eyes tighten the policy.

#### Where

`oz0 tenant tool-policy set`

Four eyes is off by default. Turned on, a change that loosens one of these waits as a change request of kind `governance` with the setting's value before and after, what loosens, and the reason; nothing changes until another admin approves it. The admin who proposed it never approves it, whatever `review-widening` says, and an API key never does. A tightening applies at once. While four eyes is on, egress widenings and credential bindings need another admin too.

```bash [Terminal]
$ oz0 tenant four-eyes acme loosening --reason "audit finding 2026-07" --decision-ref "Dnr 2026/114"
$ oz0 retention set 90 --tenant acme --reason "storage costs"
Change request cr-8d0c41aa-2f19: governance of acme, pending
  requested by user:ann just now
  setting retention: {"days":365} -> {"days":90}
  loosens: retention shortened to 90 days (was 365 days)
  reason: storage costs
Delta sha256:41e0... (review-widening second_admin)
You may not approve it: a governance change is approved by another admin than user:ann, who proposed it
Nothing changed yet: the change waits for a tenant admin's approval.
$ oz0 change approve cr-8d0c41aa-2f19 --tenant acme     # as another admin
```

Turning four eyes on is refused while the tenant has a single admin who could approve (its admins and owners, the cluster's admins and operator certificates), and turning it off is a loosening itself.

An approved change applies as its approver, after checking that the setting is still what the request saw; if someone changed it meanwhile, the approval fails and the requester asks again.

**Govern › Policy** has four eyes, under **More**; every form that changes a governance setting asks why, and a change that waits says so.

The audit trail has `governance.change_requested`, `governance.change_approved`, `governance.change_rejected` and `governance.change_applied`, and `tenant.four_eyes`.

### Concurrent governance changes

Changes made at once. A change of a governance setting is classed, and written, against the value it replaces, on whichever management server it runs.

A tenant's governance settings carry a version that every change moves on in the transaction that writes it, and a change is written only if no other change of the tenant's governance settings landed after it read the value.

A change that another overtook is refused with nothing written (`aborted`, "changed meanwhile"): read the setting again and make the change again, and it is classed against what is there now, so a change that loosens what another admin just tightened waits for review instead of undoing it.

Writes of a governance setting from elsewhere (a plugin configuration's apply, a plugin's suggested rules narrowed at install, removal or a node's listing, a tenant's region, a results grant's targets revoked with the grant or the plugin) move the version too, and only when they change something: a node's listing that narrows nothing refuses no change.

A results target added while the plugin's results grant is revoked is not written.

These writes and governed changes take the tenant's governance first, so changes made at once on several management servers wait for each other and all finish.

An approval that another change overtook between its read and its write is tried again, and still applies only while the setting is what the request saw; an approved credential binding applies whatever other governance change landed meanwhile, since its approval decided it.

Loosenings of one setting requested at the same moment, on one management server or several, are each filed as a request that waits, as they would be one after another.

Data rules are classed as the gateway reads them: rules that name no region keep a tenant pinned to a region in that region, so naming another region widens them.

### A shadow rule turned on

A governance change that turns a shadow rule of the tool policy on shows the rule's newest [governance replay](https://docs.oz0.ai/govern/governance-replay), if one ran: its ID and its summary line, for the deciding admin to read before they approve. A change never needs a replay; start one with `oz0 replay start --promote <rule ID>`.

## Related tasks and reference

- [Review assistant and job proposals](https://docs.oz0.ai/govern/reviewed-changes/proposals)
- [Review plugin configurations](https://docs.oz0.ai/govern/reviewed-changes/plugin-configurations)
- [Review and roll back changesets](https://docs.oz0.ai/govern/reviewed-changes/changesets)
- [Review changes to protected paths](https://docs.oz0.ai/govern/reviewed-changes/protected-paths)

<legacy-sections>
<span id="a-change-budget-per-plugin">

a change budget per plugin

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/protected-paths#a-change-budget-per-plugin).

<span id="a-policy-instead-of-a-person">

a policy instead of a person

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/changesets#a-policy-instead-of-a-person).

<span id="an-improvers-changesets">

an improvers changesets

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/changesets#an-improvers-changesets).

<span id="assistant-plans">

assistant plans

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/proposals#assistant-plans).

<span id="change-requests-a-job-files">

change requests a job files

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/proposals#change-requests-a-job-files).

<span id="changesets">

changesets

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/changesets#changesets).

<span id="credential-bindings">

credential bindings

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/plugin-configurations#credential-bindings).

<span id="plugin-configurations">

plugin configurations

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/plugin-configurations#plugin-configurations).

<span id="protected-paths">

protected paths

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/protected-paths#protected-paths).

<span id="rollback">

rollback

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/changesets#rollback).

<span id="skill-proposals">

skill proposals

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/changesets#skill-proposals).

<span id="the-job-never-changes-its-own-check">

the job never changes its own check

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/protected-paths#the-job-never-changes-its-own-check).

<span id="where-a-change-came-from">

where a change came from

</span>

: [Read the section](https://docs.oz0.ai/govern/reviewed-changes/changesets#where-a-change-came-from).

</legacy-sections>


## Sitemap

See the full [sitemap](https://docs.oz0.ai/sitemap.md) for all pages.
