3535 await startWorker ( )
3636 if ( publicProvisioning ) {
3737 await assertPublicProvisioning ( staticArtifactImport )
38- console . log ( "Cloudflare public provisioning gate passed: authenticated artifact staging, idempotent site allocation, scheduled import , cold-restart site read, administrator claim, login, and editable native blocks ." )
38+ console . log ( "Cloudflare public provisioning gate passed: authenticated artifact staging, idempotent site allocation, initial publication , cold-restart site read, administrator claim, native-block edit, automatic republication, and post-restart persistence ." )
3939 } else {
4040 await assertFullBootProbe ( )
4141 await assertWordPressCronDisabled ( )
@@ -113,9 +113,9 @@ try {
113113 const importedAdmin = await login ( )
114114 await assertImportedArtifactPages ( importedAdmin , imported )
115115 const duplicateStateBefore = await ( await fetch ( `${ origin } /?phase=r2-state` ) ) . json ( )
116- const duplicate = await importStaticArtifact ( staticArtifactImport , 200 )
116+ const duplicate = await importStaticArtifact ( staticArtifactImport , coordinator === "d1" ? 202 : 200 )
117117 const duplicateStateAfter = await ( await fetch ( `${ origin } /?phase=r2-state` ) ) . json ( )
118- if ( duplicate . status !== "duplicate" || duplicateStateAfter . version !== duplicateStateBefore . version || duplicateStateAfter . pointer ?. revision !== duplicateStateBefore . pointer ?. revision ) throw new Error ( "Idempotent static artifact import changed canonical state." )
118+ if ( ! ( [ " duplicate" , ... ( coordinator === "d1" ? [ "imported" ] : [ ] ) ] . includes ( duplicate . status ) ) || duplicateStateAfter . version !== duplicateStateBefore . version || duplicateStateAfter . pointer ?. revision !== duplicateStateBefore . pointer ?. revision ) throw new Error ( "Idempotent static artifact import changed canonical state." )
119119 const conflicting = await importStaticArtifact ( { ...staticArtifactImport , import : { ...staticArtifactImport . import , slug : "different-artifact-site" } } , 409 )
120120 const conflictStateAfter = await ( await fetch ( `${ origin } /?phase=r2-state` ) ) . json ( )
121121 if ( conflicting . status !== "conflict" || conflictStateAfter . version !== duplicateStateBefore . version || conflictStateAfter . pointer ?. revision !== duplicateStateBefore . pointer ?. revision ) throw new Error ( "Conflicting static artifact replay changed canonical state." )
@@ -219,7 +219,7 @@ async function assertPublicProvisioning(input) {
219219 const imported = operation ?. receipt ?. ssiResult
220220 if ( operation ?. state !== "succeeded" || imported ?. status !== "imported" || imported . staticSiteImporterVersion !== "1.3.4" || ! imported . themeSlug
221221 || ! imported . pages || Object . keys ( imported . pages ) . length !== expectedPageCount || Object . values ( imported . quality ?? { } ) . some ( ( count ) => count !== 0 )
222- || operation . receipt ?. publication ?. status !== "none " ) {
222+ || operation . receipt ?. publication ?. status !== "promoted " ) {
223223 throw new Error ( `Public provisioning did not produce a terminal import receipt: ${ JSON . stringify ( operation ) } .` )
224224 }
225225
@@ -236,7 +236,18 @@ async function assertPublicProvisioning(input) {
236236 const claim = JSON . parse ( claimBody )
237237 if ( ! claimResponse . ok || claim . credential ?. username !== "admin" || claim . credential ?. password !== password ) throw new Error ( `Administrator claim failed: ${ claimResponse . status } ${ claimBody } .` )
238238 const adminHtml = await login ( claim . credential . password )
239- await assertImportedArtifactPages ( adminHtml , imported )
239+ const importedPages = await assertImportedArtifactPages ( adminHtml , imported )
240+ const edited = await updateImportedPage ( adminHtml , importedPages . secondary )
241+ const published = await runScheduledPublicationUntil ( new URL ( edited . route , origin ) , edited . marker , "provisioned site edit publication" , 12 )
242+ assertIncludes ( published , edited . marker , "provisioned site edit publication" )
243+ await stopWorker ( )
244+ await startWorker ( )
245+ const persisted = await assertPublishedWordPressPage ( new URL ( edited . route , origin ) , "provisioned site edit after restart" , [ "publication-r2" , "publication-edge" ] )
246+ assertIncludes ( persisted , edited . marker , "provisioned site edit after restart" )
247+ const restartedAdmin = await assertAuthenticatedDashboard ( new URL ( "/wp-admin/" , origin ) )
248+ const persistedPages = await assertImportedArtifactPages ( restartedAdmin , imported )
249+ const persistedEdit = [ persistedPages . primary , persistedPages . secondary ] . find ( ( page ) => page . id === edited . id )
250+ if ( ! persistedEdit ?. raw . includes ( edited . marker ) ) throw new Error ( `Provisioned site edit was not retained as editable block content after restart: ${ JSON . stringify ( persistedPages ) } .` )
240251}
241252
242253async function assertTwoSiteIsolation ( ) {
@@ -383,18 +394,35 @@ async function createPost(adminHtml) {
383394 return { id : post . id , slug : post . slug , route : `${ link . pathname } ${ link . search } ` , title }
384395}
385396
386- async function importStaticArtifact ( input , expectedStatus = 201 ) {
397+ async function importStaticArtifact ( input , expectedStatus = coordinator === "d1" ? 202 : 201 ) {
387398 const response = await fetch ( `${ origin } /?phase=operator-static-artifact-import` , {
388399 method : "POST" ,
389400 headers : { authorization : `Bearer ${ operatorToken } ` , "content-type" : "application/json" } ,
390401 body : JSON . stringify ( input ) ,
391402 } )
392403 const body = await response . text ( )
393404 if ( response . status !== expectedStatus ) throw new Error ( `Static artifact import failed: ${ response . status } ${ body } .\nWorker output:\n${ output } ` )
394- const result = JSON . parse ( body )
395- if ( expectedStatus === 201 && ( result . status !== "imported" || result . staticSiteImporterVersion !== "1.3.4" || ! result . themeSlug
405+ let result = JSON . parse ( body )
406+ if ( expectedStatus === 202 ) {
407+ if ( typeof result . operationId !== "string" ) throw new Error ( `Queued static artifact import omitted its operation ID: ${ body } .` )
408+ for ( let tick = 0 ; tick < 10 ; tick ++ ) {
409+ await runScheduledCron ( )
410+ const operationResponse = await fetch ( `${ origin } /?phase=operator-static-artifact-operation&operationId=${ encodeURIComponent ( result . operationId ) } ` , {
411+ headers : { authorization : `Bearer ${ operatorToken } ` } ,
412+ } )
413+ const operationBody = await operationResponse . text ( )
414+ if ( ! operationResponse . ok ) throw new Error ( `Queued static artifact operation read failed: ${ operationResponse . status } ${ operationBody } .` )
415+ const operation = JSON . parse ( operationBody )
416+ if ( operation . state === "succeeded" ) {
417+ result = operation . receipt ?. ssiResult
418+ break
419+ }
420+ if ( operation . state === "failed" ) throw new Error ( `Queued static artifact operation failed: ${ operationBody } .` )
421+ }
422+ }
423+ if ( expectedStatus !== 409 && ( ! result || typeof result !== "object" || result . status !== "imported" || result . staticSiteImporterVersion !== "1.3.4" || ! result . themeSlug
396424 || ! result . pages || ! Object . keys ( result . pages ) . length || Object . values ( result . quality ?? { } ) . some ( ( count ) => count !== 0 )
397- || ! response . headers . get ( "x-wp-codebox-canonical-revision" ) || ! response . headers . get ( "x-wp-codebox-canonical-version" ) ) ) {
425+ || ( expectedStatus === 201 && ( ! response . headers . get ( "x-wp-codebox-canonical-revision" ) || ! response . headers . get ( "x-wp-codebox-canonical-version" ) ) ) ) ) {
398426 throw new Error ( `Static artifact import returned invalid evidence: ${ body } .` )
399427 }
400428 return result
@@ -420,6 +448,26 @@ async function assertImportedArtifactPages(adminHtml, imported) {
420448 return { primary, secondary : secondary ?? primary }
421449}
422450
451+ async function updateImportedPage ( adminHtml , page ) {
452+ const marker = `Provisioned site edit ${ Date . now ( ) } `
453+ const content = `<!-- wp:paragraph --><p>${ marker } </p><!-- /wp:paragraph -->`
454+ const response = await request ( `${ origin } /wp-json/wp/v2/pages/${ page . id } ` , {
455+ method : "POST" ,
456+ headers : { "content-type" : "application/json" , "x-wp-nonce" : restNonce ( adminHtml ) } ,
457+ body : JSON . stringify ( { content, status : "publish" } ) ,
458+ } )
459+ const body = await response . text ( )
460+ assertNoPhpDiagnostics ( body , "provisioned site page edit" )
461+ if ( response . status !== 200 || response . headers . get ( "x-wp-codebox-publication" ) !== "queued" || ! response . headers . get ( "x-wp-codebox-publication-job" ) ) {
462+ throw new Error ( `Provisioned site page edit did not queue publication: status=${ response . status } publication=${ response . headers . get ( "x-wp-codebox-publication" ) } body=${ body } .` )
463+ }
464+ const updated = JSON . parse ( body )
465+ const raw = updated . content ?. raw
466+ if ( typeof raw !== "string" || ! raw . includes ( marker ) || / < ! - - w p : (?: h t m l | f r e e f o r m ) \b / . test ( raw ) ) throw new Error ( `Provisioned site page edit was not retained as native block content: ${ body } .` )
467+ const link = new URL ( updated . link )
468+ return { id : page . id , marker, route : `${ link . pathname } ${ link . search } ` }
469+ }
470+
423471async function updatePost ( adminHtml , post , previousPublicationRevision ) {
424472 const title = `Automatically published ${ Date . now ( ) } `
425473 const response = await request ( `${ origin } /wp-json/wp/v2/posts/${ post . id } ` , {
@@ -728,10 +776,11 @@ async function assertCoordinatorAdoption() {
728776 if ( ! adoption . ok || ! adopted . adopted || adopted . version !== before . version || adopted . pointer ?. revision !== before . pointer ?. revision ) {
729777 throw new Error ( `Exact coordinator adoption failed: status=${ adoption . status } payload=${ JSON . stringify ( adopted ) } .` )
730778 }
779+ const divergentRevision = "00000000-0000-4000-8000-000000000000"
731780 const divergent = await fetch ( `${ origin } /?phase=operator-adopt` , {
732781 method : "POST" ,
733782 headers : { authorization : `Bearer ${ operatorToken } ` , "content-type" : "application/json" } ,
734- body : JSON . stringify ( { pointer : before . pointer , version : before . version + 1 } ) ,
783+ body : JSON . stringify ( { pointer : { ... before . pointer , revision : divergentRevision , manifestKey : before . pointer . manifestKey . replace ( before . pointer . revision , divergentRevision ) } , version : before . version } ) ,
735784 } )
736785 if ( divergent . status !== 409 ) throw new Error ( `Divergent coordinator adoption was not rejected: ${ divergent . status } ${ await divergent . text ( ) } .` )
737786 await assertCoordinatorBackend ( )
0 commit comments