Sync policies
Sync policies live under sync in shelve.json (and can be enforced on the server per project). They answer: should a push from my laptop overwrite production? Does pull replace my whole .env or merge?
Quick example
{
"$schema": "https://shelve.cloud/schema.json",
"slug": "my-team",
"project": "my-app",
"defaultEnv": "development",
"sync": {
"protectedEnvironments": ["production", "preview"],
"default": {
"onPushConflict": "overwrite",
"pullMode": "replace"
},
"environments": {
"development": {
"sourceOfTruth": "local",
"onPushConflict": "overwrite"
},
"production": {
"sourceOfTruth": "remote",
"allowPush": false,
"pullMode": "merge"
}
}
}
}
Policy fields
| Field | Values | Effect |
|---|---|---|
sourceOfTruth | remote | local | Hint for shelve sync: pull when remote, push when local. |
onPushConflict | overwrite | skip | fail | prompt | When a key exists on Shelve with a different value than local. Default: overwrite. |
pullMode | replace | merge | replace: rewrite .env (legacy). merge: remote keys win; local-only keys are kept. |
allowPush / allowPull | boolean | Hard block with PUSH_BLOCKED / PULL_BLOCKED. |
protectedEnvironments | string[] | Sets allowPush: false for listed env names. |
requireConfirmation | boolean | Extra confirmation even if confirmChanges is false. |
Per-environment overrides go in sync.environments.<name>. Defaults apply via sync.default.
Server policies
Project Settings → Sync policy stores syncPolicy on the project. Server rules cannot be relaxed from shelve.json: if the server sets allowPush: false, the CLI cannot override it.
Protected environments reject API writes with ENV_PROTECTED.
Commands
shelve diff
Compare local envFileName with Shelve (no writes). Safe for agents with --json (no secret values).
shelve diff --env staging
shelve --json diff --env staging
shelve diff --env staging --show-values
shelve sync {#sync-command}
Apply the effective policy for the environment:
sourceOfTruth: remote→ pull (respectspullMode)sourceOfTruth: local→ push (respectsonPushConflict)
shelve sync --env development
shelve sync --env production --dry-run
shelve sync --yes --env staging
--dry-run reports the planned action and diff without writing.
Environment variables
| Variable | Effect |
|---|---|
SHELVE_SYNC_ALLOW_PUSH=0 | Disables push for all environments in this process |
SHELVE_SYNC_ALLOW_PULL=0 | Disables pull for all environments |
Error codes
| Code | Meaning |
|---|---|
PUSH_BLOCKED | allowPush: false or protected environment |
PULL_BLOCKED | allowPull: false |
SYNC_CONFLICT | onPushConflict: fail (or prompt in non-interactive mode) |
ENV_PROTECTED | Server rejected a write to a protected environment |
See Troubleshooting.
Monorepos
Put protectedEnvironments in the root shelve.json; package-level files can override sync.environments for each app.