What has to be recovered#
The operator is stateless compute plus a store:
- The compute is a Cloudflare Worker and the EU-pinned Durable Object it forwards to, redeployed from the one compiled bundle, whose hash is pinned in the provenance. The object keeps no state of its own: everything durable is in the store.
- The store holds the governance events, member public keys, the signed verdict ledger, pKYC triggers and the webhook outbox.
- Nothing else. The operator holds no secret and no raw data, so there is nothing else to restore.
Recovery point: why it is better than the store's#
Two independent copies of everything that matters exist outside the operator:
- Every governance event is signed by the member that made it, and members keep them.
- Every verdict is signed by the operator and held by the members whose legs authenticated. They receive it in the response, by webhook and through the SIEM export.
server/recovery-drill.test.js proves that the verdict log rebuilds from the members' copies alone to the same root, with every copy verified before re-admission, so a rebuild cannot smuggle a changed verdict in. For verdicts, the effective recovery point is therefore zero for any member that keeps its copies, whatever happens to the operator's store.
The store itself follows its provider's backup regime (see sub-processors). Its point-in-time setting is not published here. Confirm it before quoting a store-level recovery point.
Recovery time: measured#
node server/bench-recovery.js restores a store holding n signed verdicts, boots a fresh operator, and asks it for the signed head of the log, which reads and hashes every row.
| Verdicts | Restore to a signed head |
|---|---|
| 1,000 | 0.25 s |
| 10,000 | 2.4 s |
Measured on 28 September 2026, on an Intel Core i5-8265U laptop (Node 24.16.0, Windows, in-memory store). It excludes the time to read the rows back from a remote database, and the time to redeploy the Worker. Run the script on your own hardware; the numbers move with it.
| Step | Target | Basis |
|---|---|---|
| Redeploy the operator from the pinned bundle | Minutes | One command (wrangler deploy), or a rollback to the previous version |
| Restore the store from backup | The provider's restore time | Not measured here |
| Operator ready on the restored store | Seconds per 10,000 verdicts | Measured above |
| Rebuild the log from members' copies, if the store is lost | Minutes to collect; seconds to rebuild | The recovery drill |
These are targets with their basis stated, not an SLA. No availability commitment is published until someone operates the service under one.
What is tested#
The recovery drill (server/recovery-drill.test.js) runs on every build:
- back up, restore, and require an identical registry and an identical log root;
- rebuild from members' copies, and require the same root;
- refuse an altered copy.