Copy, adopt, verify
Edge Evidence · Overview · 1 One record · 2 Copy and verify · 3 Lab runs · 4 The model · 5 Checks and gaps
A write call that returns successfully is a useful event. It is not the same as reading the destination independently and checking that it holds the intended bytes. Replication keeps those two things apart. It copies already-finalised, immutable evidence onto a target that was bound in advance. It doesn’t capture or process anything, choose a destination for the operator, provision storage, or create credentials.
Bind the destination before trusting it
The worker checks the configured target against the database, and checks the target’s own identity marker. A reachable directory or bucket name isn’t enough authority to write there: if the identity doesn’t match, it fails closed. The core talks to a provider-neutral target contract, not to a provider’s SDK, so a mounted filesystem and a cloud bucket are two adapters behind the same rules.
Three destination states, two successful paths
Before copying, the worker re-hashes the local source against the expected object. Then it looks at the destination:
| Destination | What the worker does |
|---|---|
| Object absent | Create it exclusively, then read it back |
| Exact expected bytes already present | Read back and adopt; don’t rewrite |
| Different bytes present | Refuse with destination_collision (exit code 4); keep the conflicting bytes and leave the record PENDING |
The refusal is the important case. “Upload again if unsure” would erase a contradiction. Refusing keeps it, with a recorded error, for a person to look at.
Three commands, three questions
reconcilerevisits work already known to be pending. It checks the target identity, cleans up its own transient partial files, and can adopt exact objects it finds.runreconciles first, then discovers eligible objects, records each attempt, and creates or adopts. A recorded failure stays a failure.verifyopens the database read-only and checks every replica already marked verified against the target. It creates nothing.
So “perform the copy” and “check it afterwards” are different operations. verify still reads the target to compare bytes, so read-only database access doesn’t mean no I/O.
The local trace
The standalone demonstration builds two synthetic source objects and a local destination, with one destination object pre-filled with the exact expected bytes:
| Step | Recorded result |
|---|---|
run over both objects | 2 discovered, 1 published (created), 1 adopted, 2 verified; one transient partial cleaned up |
Independent verify | 2 verified; nothing discovered, published or adopted |
| Exact rerun | 0 published, 0 adopted, 0 verified; database rows unchanged |
| Separate collision case | Exit code 4, destination_collision; conflicting bytes kept; record stays PENDING with the error |
These are the demonstration’s assertions and integration test, not a live storage run. The demo also substitutes the NFS mount check with a local directory, so it says nothing about a real NFS service, a real bucket, credentials or network durability.
Once against a real bucket
One approved run used a disposable real Google Cloud Storage bucket, in two phases under separate approvals:
- A read-only inventory froze one exact candidate, with no worker running and no change at the provider.
- The approved run found the target object already matching the expected 522 bytes and digest. It adopted the object instead of overwriting it, read it back independently, and changed only the authorised replica row.
The retained records show one approved attempt, no retry, and an unchanged destination inventory. That is stronger than a simulated object store, and much narrower than provider coverage. It exercised adoption only: the create path hasn’t run against a real provider, and nothing here covers bucket policies or continuous replication. No public receipt of that run exists. The record is the project’s retained summary.
The Proof view: one handoff, replayed
The hosted demo’s Proof view follows one retained synthetic result in which the Processor’s output was handed to Replication. You step through it by hand:
| Step | What the snapshot records |
|---|---|
| Processor | A derived report, with its SHA-256 recorded as the handoff source |
| Handoff | Replication expected exactly that size and digest, so the object it copied is the Processor’s output, not a similar one |
| Replication | First run: one object discovered, inserted and published; none adopted; one verified |
| Readback | A separate verification pass read the target back: same byte size and digest as the source; state VERIFIED after one attempt, with no recorded error |
| Replay | Running the same work again published nothing and inserted nothing |

Hosted Gateway capture, 25 October 2026. Proof at step 3 of 5. Each row quotes a recorded field by its JSON path; the line marked Note is the page’s own wording.
The snapshot was retrieved on 19 October 2026 and is marked as cached. Its original execution time is unknown. Stepping through it runs no worker, reads no storage and calls no model. It is one object, in its own fixture, so its counts are never added to the two-object trace above.
What the snapshot doesn’t contain matters too. The Processor’s resume and busy-lock cases, and Replication’s adoption and refusal, appear in it only as “standalone proofs passed”. The walkthrough says so instead of illustrating steps it has no record of.
Basis: the public Replication package’s architecture notes, worker code, demonstration and integration test (demo/run_demo.py, tests/test_integration.py), as traced in the Replication readback chapter; the real-bucket record as summarised in Development and operations; and the retained Proof snapshot in the public reference platform. No new runs were made for this page.
Previous: One record, end to end · Next: Letting operation decide