❯ Reproducibility
A deployment tool tells you what happened. This one leaves the record.
Every upward change originates in a file you committed — which makes it reviewable before it happens and findable afterwards. An upward effect with no source in the repository is refused, not warned about.
Why a diff has to be quiet
A record nobody reads is not a record. The whole principle collapses the moment a routine pull produces four hundred changed files, because at that point everyone stops reading the diff — so the export rules exist to keep it boring:
- One item per file, so a change touches only what changed.
- Sorted keys, so serialisation order is not a diff.
- URLs as placeholders, so the same page pulled from two environments is byte-identical.
- Volatile fields stripped — timestamps and counters that move on their own.
- Written through the workspace, so a file whose bytes are unchanged keeps its modification time and never appears in the diff at all.
The last one has a test that pulls twice and asserts the mtime did not move. Without it, “a pull that changes nothing writes nothing” is a wish.
Three states, not two
The repository is one of three, and cwp status reports all three at once. A path can be committed, current on this machine, and still have drifted on the host — and that is the case nobody notices until they need to know what changed.
| Path | repo | local | remote | State |
|---|---|---|---|---|
bricks/ | ✓ | ✓ | ✗ | 3 global classes differ on prodin step, as far as this machine can see |
content/ | ✓ | ✗ | ✓ | 2 pages edited locally, uncommitted2 pages edited locally, uncommitted |
plugins.yml | ✓ | ✓ | ✓ | in stepin step, as far as this machine can see |
Three states, not two. A path can be committed and current locally and still have drifted on the host — which is the case nobody notices until they need to know what changed.
Without --remote the third column is not wrong, it is unknown — and says so instead of guessing. Everything the repository and this machine can settle between themselves still answers.
The escape hatch, and why it still leaves a file
Not every write can come from a committed file — an ad-hoc call is sometimes the honest thing to do. So the point is not to forbid it. The point is that it leaves a file behind: --adhoc writes the payload to .cwp/adhoc/, says plainly that the change is not reproducible, and is refused outright on a protected environment.
The guard that enforces itWhat it buys once an agent is doing the typing