Idempotency
Sinter resources are idempotent: when the target already matches the desired
state, apply performs no mutation for that resource.
What this means in practice
Section titled “What this means in practice”sinter apply --host web01 --sudo recipe.yaml # changes appliedsinter apply --host web01 --sudo recipe.yaml # ok — zero mutations- A
packageresource does not reinstall an installed package or re-remove an absent one. - A
fileresource that already has the desired content, mode, and ownership is not rewritten. - A
servicealreadyrunningandenabledis left untouched. - Handlers run only when something changed — an idempotent second apply triggers none.
- A manager that is already synchronized is not reloaded: with no pending
systemd input change and
NeedDaemonReload=no, a second apply issues zerodaemon-reloadcalls.
Re-observation, not replanning
Section titled “Re-observation, not replanning”apply does not trust an earlier plan. Every stateful resource is observed
again immediately before the mutation decision, so drift between plan and
apply is handled correctly.
Command resources and guards
Section titled “Command resources and guards”command is not inherently idempotent — it runs when reached. Use creates
or removes guards to make it idempotent:
- id: update_index type: command with: program: /usr/bin/touch args: ["/var/lib/myapp/indexed"] creates: /var/lib/myapp/indexedWhen /var/lib/myapp/indexed exists, the command is not executed; the
resource reports success with no change and dependencies stay satisfied.
Truthful reporting
Section titled “Truthful reporting”A resource that mutated successfully but failed a later step still reports that it changed. Verification failures are never flattened into “success”.