You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: packages/runtime-cloudflare/README.md
+6Lines changed: 6 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -26,6 +26,12 @@ WordPress server files, browser assets, and pinned runtime dependencies are sepa
26
26
27
27
Canonical Cloudflare boots patch only the assembled PHP MEMFS copy of `/wordpress/wp-settings.php` after the R2 WordPress corpus is materialized and before WordPress executes. The disabled-cron scheduling policy requires exactly one canonical `do_action( 'init' );` needle and fails closed otherwise. When `DISABLE_WP_CRON` is true, it removes only core's `wp_cron`, `wp_schedule_delete_old_privacy_export_files`, and `wp_schedule_update_checks` callbacks through public `remove_action()` before executing the original `init` call once. This prevents browser requests from recreating cron work outside the explicit scheduled-Worker transaction.
28
28
29
+
## Coordinator Cutover
30
+
31
+
The authenticated mutation-fence endpoints provide a bounded cutover window without interrupting anonymous published reads. `POST ?phase=operator-fence-acquire` accepts `{"ttlSeconds":30}` through `{"ttlSeconds":600}` and returns an opaque token plus expiry. While active, both coordinators reject new canonical leases, reset, adoption, manual publication, scheduled publication, and cron work with a conflict. `POST ?phase=operator-fence-renew` accepts the token and a fresh bounded TTL; `POST ?phase=operator-fence-release` accepts the token. Expiry automatically reopens mutations, and status responses never expose the token.
32
+
33
+
Use authenticated `GET ?phase=operator-fence-status` after acquisition to export a coherent cutover envelope. It includes the coordinator store, pointer, version, matching commit receipt, validated R2 manifest identity, fence expiry, and a `coherent` verdict. Coherence also reads every referenced canonical object and verifies its declared size and SHA-256, so an incomplete target cannot be promoted. Adopt that exact pointer/version into the target coordinator, require the target status envelope to match, then promote the target Worker before the source fence expires. The first target mutation must commit version `N+1`. Rollback uses the same sequence in reverse after fencing the active target; relying on an unfenced status read is not a lossless cutover procedure.
34
+
29
35
## Static Artifact Import
30
36
31
37
An authenticated `POST ?phase=operator-static-artifact-import` materializes a verified website artifact into the existing canonical site. The request is limited to 16 KiB and references an immutable JSON object at `sites/default/import-artifacts/<sha256>.json`; the Worker requires the declared R2 key, size, and SHA-256 to agree before acquiring a coordinator lease. The canonical `blocks-engine/php-transformer/site-artifact/v1` payload is limited to 4 MiB serialized, 500 safe unique files, 8 MiB per decoded file, and 32 MiB decoded in aggregate.
thrownewRevisionConflict("D1 coordinator adoption requires empty or exactly matching state without an active lease.",state.lease_expires_at??undefined)
thrownewRevisionConflict("Coordinator reset is blocked by an active canonical lease or cutover fence.",fence?.expires_at??state.lease_expires_at??undefined)
256
+
}
162
257
return{reset: true}
163
258
}
164
259
@@ -179,6 +274,10 @@ async function readRow(database: D1Database): Promise<StateRow> {
@@ -216,6 +315,7 @@ function ensureSchema(database: D1Database): Promise<void> {
216
315
)`).run()
217
316
awaitdatabase.prepare(`INSERT OR IGNORE INTO wp_codebox_state (site_id, version) VALUES (?, 0)`).bind(SITE_ID).run()
218
317
awaitdatabase.prepare(`CREATE TABLE IF NOT EXISTS wp_codebox_commits (site_id TEXT NOT NULL, version INTEGER NOT NULL, revision TEXT NOT NULL, manifest_key TEXT NOT NULL, persisted_at TEXT NOT NULL, PRIMARY KEY (site_id, version))`).run()
318
+
awaitdatabase.prepare(`CREATE TABLE IF NOT EXISTS wp_codebox_fences (site_id TEXT PRIMARY KEY, token TEXT NOT NULL, expires_at INTEGER NOT NULL)`).run()
if(!Number.isSafeInteger(ttlMs)||ttlMs<1||ttlMs>MAX_REVISION_LEASE_MS)thrownewRevisionConflict(`Revision lease TTL must be between 1 and ${MAX_REVISION_LEASE_MS} milliseconds.`)
0 commit comments