SEO / Portfolio / Public Site

Production Reliability Architecture for the InternationalIntelligence.org Daily Brief

Report summary

I assess the most plausible failure as production split-brain across execution, origin, cache, release, and browser layers , not failure of the internal Daily Brief workflow itself.

Status
Research archive item
Category
SEO / Portfolio / Public Site
Length
8,453 words
Reading time
39 minutes
Report type
architecture

Key topics

  • SEO / Portfolio / Public Site
  • SEO
  • Portfolio
  • Public Site
  • .NET
  • Runtime
  • Semantic Systems
  • Research Archive
  • Strategy

Research provenance

Archive status
Research archive item
Content identity
sha256:58f8080a2fdb40a07076258b8420848a88be4b73f01b996c30311757269e3a7f

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

Source availability: 20 citation markers in the source export have no recoverable source links. Those markers are omitted from this reader; any supplied bibliography and ordinary links remain. Check the original sources before relying on the cited claims.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

Executive finding and research method

Executive finding

I assess the most plausible failure as production split-brain across execution, origin, cache, release, and browser layers, not failure of the internal Daily Brief workflow itself.

A workflow test can pass while the public site still looks broken when any of the following are true:

  • The scheduler does not execute, executes late, overlaps, or invokes an obsolete release.
  • PHP CLI advances state using a different configuration, user, filesystem, secrets set, or database target than PHP-FPM.
  • An alternate hostname, virtual host, CDN origin, or document root serves a different release or site instance.
  • A reverse proxy, CDN, browser cache, or service worker returns stale status JSON.
  • A browser tab displays provisional HTML or local state after polling has been throttled or suspended.
  • An old response arrives after a newer response and overwrites it.
  • A process exists, but its last meaningful progress is stale.
  • A deployment changes the web release while cron, OPcache, workers, or service-worker caches remain attached to the previous release.

The assignment reports that provider connectivity works and that process IDs, monotonic revisions, polling, cross-tab synchronization, trigger leasing, canonical-host handling, and versioned assets have already been attempted. Those controls are necessary but cannot prove that scheduled production execution and public delivery use the same release, site instance, authoritative datastore, filesystem, origin, and cache policy. I therefore treat the uploaded project description as the case study and as the source of reported—but not independently verified—system facts.

My central architectural recommendation is:

Use one server-side publication authority, backed by transactional idempotency and a lease with an expiry; let one primary scheduler and one independently monitored fallback submit trigger requests; expose immutable release and site-instance identities through every execution and status record; make status endpoints uncacheable at every layer; and treat every browser representation as provisional until reconciled with the authoritative API.

An external scheduler may request work, but it must never decide that a publication cycle exists, choose a new process ID, increment a revision, bypass eligibility rules, or declare success. Those decisions belong to the server authority.

Scope and limitations

I have no source-code, shell, hosting-panel, CDN, DNS, credentials, deployment logs, scheduler logs, database records, or private runtime-state access. Consequently, I cannot identify the actual fault with certainty. I can provide a production architecture, evidence requirements, safe diagnostics, failure hypotheses, and acceptance tests that distinguish likely causes without relying on privileged access.

Details not supplied remain unspecified, including:

ItemStatus
Hosting provider and control panelUnspecified
Linux distribution and init systemUnspecified
PHP and PHP-FPM versionsUnspecified
Database or state-store technologyUnspecified
CDN and reverse-proxy vendorsUnspecified
Canonical hostnameUnspecified
Alternate hostnamesUnspecified
Current release identifierUnspecified
Site-instance identifierUnspecified
Existing scheduler type and scheduleUnspecified
Publication timezone and eligibility ruleUnspecified
Service-worker presence and scopeUnspecified
Number and location of active originsUnspecified

Methodology

I modeled the system as a chain of independently falsifiable contracts:

  1. A scheduler emits an authenticated trigger.
  2. The canonical origin validates identity and mode.
  3. The server authority determines eligibility.
  4. A transaction reserves or resumes a publication process.
  5. A worker advances state while renewing its lease and heartbeat.
  6. The status API serializes authoritative state.
  7. Reverse proxies and CDNs forward rather than reuse that response.
  8. Browser code reconciles snapshots monotonically.
  9. Cross-tab messaging accelerates—but never creates—convergence.
  10. Deployment preserves release and state compatibility through rollout and rollback.

For normative behavior, I prioritized current standards and official implementation documentation as of August 1, 2026. HTTP cache semantics come from RFC 9111; request-target, host, and redirect semantics from RFC 9110; forwarded-header risks from RFC 7239; PHP behavior from the PHP manual; scheduler behavior from cron, systemd, cPanel, Google Cloud, and AWS documentation; and browser behavior from WHATWG, W3C, Chromium, Mozilla, and WebKit documentation. RFC 9111 expressly distinguishes shared and private caches and specifies that no-cache allows storage but requires successful validation before reuse, whereas no-store prohibits storage by conforming caches.

Evidence-source comparison

Source classPrimary use in this reportStrengthLimitation
IETF RFCsHost routing, redirects, caching, forwarded headersNormative Internet standardsProducts can be misconfigured or nonconforming
PHP manualCLI/FPM configuration, pools, OPcacheOfficial implementation documentationHosting vendors may patch or wrap PHP
cron/systemd manualsScheduling, environment, catch-up, service limitsDirect operational semanticsCron implementations differ
Cloud scheduler documentationRetry, at-least-once delivery, deadlines, DSTCurrent managed-service contractVendor-specific behavior
WHATWG/W3C specificationsBroadcastChannel, storage, service workers, page lifecycleBrowser-platform definitionsBrowsers retain implementation latitude
Browser-vendor documentationThrottling, suspension, lifecycle behaviorDocuments real implementation behaviorPolicies can change between versions
CDN/reverse-proxy documentationOrigin-header handling and overridesDescribes actual edge controlsExact behavior depends on account configuration
Recent academic researchHidden-cache and service-worker risk contextEmpirical evidence beyond advertised headersDoes not replace product-specific diagnostics

Recent research reinforces the need for active cache testing rather than trusting response labels alone. A 2024 study proposed timing-based discovery of hidden web caches and reported that some caches did not advertise their involvement through standard status headers; this supports using paired cache-busted and ordinary synthetic requests as diagnostic evidence, not as the normal freshness mechanism.

End-to-end execution model

Production path

The production contract should be understood as this chain:

LayerRequired proofTypical “tests pass, site broken” failure
Scheduler registrationEnabled schedule, next-run time, UTC rule, target release strategyNo cron entry, disabled panel job, wrong user
Trigger deliveryTrigger ID, attempt number, receipt timestamp, authenticated principalRequest blocked, timed out, retried, delivered to alternate origin
Canonical-origin gateObserved host, canonical origin, proxy trust resultState initialized before redirect; forwarded host trusted from the Internet
Authority transactionSite instance, cycle key, reservation resultDuplicate process creation or stale permanent lock
Worker runtimePHP binary, SAPI, INI files, extensions, UID, CWD, releaseCLI uses another PHP or release
State persistenceDatabase identity, schema contract, filesystem identityCLI and web point to different state stores or mounts
Publication progressMonotonic revision, stage, heartbeat, meaningful-progress timePID exists but process is stalled
Status serializationCurrent process and release contractAPI reads old database, old replica, or old release
Proxy/CDN deliveryAge, cache status, origin request ID, no-store complianceCached JSON returned
Browser reconciliationRequest sequence and accepted process/revisionDelayed response overwrites newer state
Cross-tab propagationCode-only snapshot notificationLocal message mistaken for server authority
LocalizationSame identifiers and codes in English and SpanishLocalized prose interpreted as state

A successful internal workflow test ordinarily validates only a subset of these rows. It does not prove that cron exists, that it invokes the same release as the website, that a public hostname reaches that release, or that the status response was fetched from the authority.

Applied case-study choice

I chose the InternationalIntelligence.org Daily Brief production path because the uploaded assignment supplies a concrete, plausible system with scheduler, PHP, CDN, browser, bilingual, and deployment concerns. This is preferable to inventing an unrelated example, while still requiring me to mark all unobserved implementation details as unspecified.

The likely causal families are:

PriorityFailure familyWhy it fits the reported symptomDecisive evidence
CriticalScheduler absent or wrong targetInternal manual tests pass; unattended publication does notScheduler execution log tied to trigger ID and release
CriticalRelease or document-root split-brainSome hosts/tabs/languages show different behaviorResponse headers expose different release/site-instance IDs
CriticalStatus JSON cachedBack end progresses but public display remains oldRepeated requests show nonzero Age, edge hits, or identical old snapshot-generation time
HighCLI/FPM driftManual web test works while cron PHP failsCLI and web doctor reports differ
HighStale or non-expiring leaseTrigger arrives but no process can reserve workLease owner, expiry, database clock, last heartbeat
HighService-worker interceptionOrigin headers look correct while one browser remains staleDevTools or synthetic clean profile shows service-worker response
HighDelayed response raceTabs intermittently regressRequest sequence logs show old response accepted after new response
MediumBackground suspensionActive tab updates; inactive/mobile tab does notVisibility and poll telemetry
MediumDST or timezone mismatchFailure clusters near cycle boundary or DST transitionUTC schedule, server time, eligibility calculation
MediumProvider/API issueReportedly less likely because connectivity worksProvider request IDs and provider-state records

Reliability timeline

timeline
    title Daily Brief production reliability lifecycle
    Scheduler configuration : Define UTC cadence
                            : Bind target and credentials
    Trigger receipt          : Validate trigger contract
                            : Record immutable trigger ID
    Reservation              : Evaluate next eligible cycle
                            : Atomically create or resume process
                            : Acquire expiring lease
    Advancement              : Poll provider
                            : Persist stage and revision
                            : Renew heartbeat and lease
    Publication              : Commit bilingual evidence
                            : Mark meaningful progress
    Status delivery          : Generate no-store snapshot
                            : Expose release and site-instance IDs
    Browser convergence      : Fetch authoritative API
                            : Reject stale responses
                            : Notify other tabs
    Deployment               : Switch immutable release
                            : reset FPM OPcache
                            : purge only intended CDN objects
                            : verify service-worker compatibility

Entity-relationship model

erDiagram
    SITE_INSTANCE ||--o{ RELEASE : serves
    SITE_INSTANCE ||--o{ PUBLICATION_CYCLE : owns
    RELEASE ||--o{ TRIGGER : receives
    TRIGGER }o--|| SITE_INSTANCE : targets
    PUBLICATION_CYCLE ||--o{ PROCESS : attempts
    PROCESS ||--o{ RESERVATION : protected_by
    PROCESS ||--o{ HEARTBEAT : emits
    PROCESS ||--o{ SNAPSHOT : produces
    PROCESS ||--o{ EVIDENCE_ITEM : accumulates
    RELEASE ||--o{ SNAPSHOT : serializes
    BROWSER_CLIENT }o--o{ SNAPSHOT : observes

    SITE_INSTANCE {
        string site_instance_id PK
        string canonical_origin
        string state_store_identity
    }
    RELEASE {
        string release_id PK
        string contract_version
        string asset_manifest_hash
    }
    PUBLICATION_CYCLE {
        string cycle_key PK
        date target_date
        timestamp next_eligible_at
    }
    TRIGGER {
        string trigger_id PK
        string trigger_type
        timestamp requested_at_utc
        string mode
    }
    PROCESS {
        string process_id PK
        int revision
        string stage_code
        timestamp last_meaningful_progress
    }
    RESERVATION {
        string lease_token PK
        timestamp acquired_at
        timestamp expires_at
        string owner
    }
    HEARTBEAT {
        timestamp observed_at
        string health_code
        int revision
    }
    SNAPSHOT {
        string snapshot_id PK
        timestamp generated_at
        int revision
        string release_id
    }
    EVIDENCE_ITEM {
        string evidence_id PK
        string type_code
        string locale_scope
    }
    BROWSER_CLIENT {
        string client_instance_id PK
        string origin
        string locale
    }

The database, not the operating-system PID, should own process identity. An OS PID is host-local, reusable, and potentially absent for HTTP or managed-function execution. It can be recorded as supporting evidence, but process_id should be an application-generated immutable identifier.

Scheduler architecture and authority contract

Scheduler-model comparison

Cron behavior is implementation-specific around daylight-saving transitions. Traditional Vixie-style documentation warns that nonexistent local times may never match and repeated times may match twice, while Cronie documents compensation for clock changes of less than three hours. That difference alone is sufficient reason to schedule the authority in UTC and compute local publication eligibility explicitly in application code.

Systemd timers can persist missed calendar activations and start a service after downtime when Persistent=true, while service units provide explicit users, working directories, environments, runtime limits, exit states, logs, and credential mechanisms.

Managed schedulers should be treated as at-least-once submitters. Google states that duplicate requests are possible in rare circumstances and instructs handlers to be idempotent; it also recommends UTC when an exact cadence must avoid DST anomalies. AWS EventBridge Scheduler documents at-least-once delivery, configurable retries, event retention, and dead-letter queues.

ModelDelivery and missed-run behaviorOverlap and catch-upRuntime and environmentFailover, cost, and complexityAssessment
Traditional system cron invoking PHP CLIBest-effort local invocation; no inherent durable delivery receipt; downtime normally loses runs unless paired with another mechanismOverlap is possible; use server-side lease plus optional flock; catch-up is not intrinsicMinimal environment; unspecified CWD unless command changes it; must use absolute PHP/script paths and explicit INI; stdout/stderr usually mailed or redirectedHost-bound; low cost; low-to-medium operational complexityAcceptable primary on one well-managed host, but only with heartbeat monitoring and idempotency
Hosting-control-panel cronUsually wraps system cron; UI simplifies registration but can hide PHP path, environment, mail, and execution limitsOverlap possible; panel documentation itself warns to leave enough completion timeVendor-selected user, PATH, shell, PHP version, and resource limits; absolute paths requiredTied to hosting account; low marginal cost; limited observabilityViable on shared hosting if doctor output and logs are externally retained
Systemd timer plus serviceDurable local orchestration; Persistent=true can catch up missed calendar activationService activation and unit state make overlap easier to control; explicit timeout and failure handlingStrongest local control over user, group, CWD, environment, mounts, credentials, logging, and runtimeHost-bound unless duplicated; no service fee; medium complexityPreferred local scheduler on a controlled Linux server
Cloud scheduler or authenticated HTTP triggerAt-least-once with retries and provider logs; delivery can fail independently of origin executionProvider may serialize attempts, but duplicates remain possible; catch-up and retry policy are vendor-specificHTTP deadline, network path, identity token, and origin limits replace CLI environment concernsIndependent of host and useful for detecting local scheduler failure; low cost; medium complexityStrong primary or fallback, provided it is only a trigger submitter
Queue worker or managed scheduled functionQueue commonly provides at-least-once delivery; durable backlog and retry/DLQ optionsConsumer concurrency must be limited or made idempotent; backlog supplies catch-upExplicit image/runtime, secrets, IAM, and time limits; filesystem may be ephemeralStrong host failover; variable cost; higher architecture complexityBest when advancement naturally decomposes into short resumable steps
Redundant schedulers with server idempotencyHighest trigger availability, but deliberately produces duplicate requestsOnly authority transaction prevents duplicate work; each trigger records its own attemptMixed environments are acceptable because the trigger payload is normalizedBetter failover; higher monitoring and testing burdenRecommended as primary plus delayed fallback, not simultaneous independent authorities

cPanel’s current documentation warns that jobs can overlap if scheduled too frequently, tells operators to use absolute paths, and notes that discarding stdout and stderr with /dev/null 2>&1 disables useful notification evidence.

Detailed operational comparison

ConcernCron / panel cronSystemd timerExternal HTTP schedulerQueue or managed function
Execution guaranteeNo end-to-end guarantee without monitoringLocal start and failure state recordedProvider delivery contract with retry; still at-least-onceDurable queue offers strongest retry semantics
At-least-once possibilityYes, through overlap, DST, manual runsYes, through retries or multiple timersExplicitly yes for common managed productsNormally yes
Overlap preventionAuthority lease; shell lock is secondaryUnit state plus authority leaseAuthority leaseConsumer concurrency plus authority lease
Missed runUsually lostCatch-up possible with persistent calendar timerProduct retry/catch-up rulesMessage remains pending until retention expires
Maximum runtimeHosting and shell limitsRuntimeMaxSec= or equivalentHTTP deadline; Cloud Scheduler documents product-specific deadlinesFunction/worker limit
EnvironmentSparse and shell-dependentDeclarativeRequest headers/body and workload environmentDeclarative deployment environment
Working directoryOften home or implementation-dependentExplicit WorkingDirectory=Not applicable to scheduler; application decidesExplicit image/function configuration
PHP executableMust be absoluteAbsolute ExecStart=Web PHP/FPM or application serviceRuntime image or function version
PHP configurationExplicit -c or verified defaultExplicit -c, environment, extensionsFPM or web runtimeImage-controlled
Filesystem userCron accountExplicit User=/Group=Web service userWorker identity
Secret accessOften missing web secretsCredentials or restricted filesIAM/OIDC/HMAC; origin secretsIAM/secret manager
TimezoneDaemon/server/CRON_TZ; implementation-sensitiveExplicit calendar zone; prefer UTCUsually explicit IANA zone; prefer UTCUTC event plus app eligibility
stdout/stderrMail or redirected filesJournal and unit statusProvider request/execution logsCentralized logs
Exit-code captureMail/wrapper requiredNative unit resultHTTP status is only trigger acceptance, not necessarily publication completionNative task status and DLQ
Deployment couplingOften hard-coded pathUnit can target stable launcher/current symlinkTargets stable canonical endpointVersioned task/function
Host failoverNone by defaultNone by defaultScheduler independent; origin still needs failoverManaged platform typically supports it
CostLowestLowestUsually lowHigher but scalable
ComplexityLow, with hidden risksModerateModerateHighest

For a small-to-medium PHP publication site, I recommend:

  • Primary: systemd timer where server control exists; otherwise an authenticated managed HTTP scheduler.
  • Fallback: an independently hosted authenticated scheduler delayed by a grace interval.
  • Authority: one transactional server endpoint or worker command shared by all trigger types.
  • Execution: short, resumable advancement steps rather than one long monolithic request.
  • Monitoring: independent freshness alerting based on last_meaningful_progress, not merely scheduler success.
  • Timezone: scheduler cadence in UTC; publication date derived from a named IANA timezone inside the authority.
  • Idempotency: unique cycle key such as (site_instance_id, target_date, edition_type) with a database uniqueness constraint.

The fallback should not run exactly with the primary. It should ask, for example, five or ten minutes later whether the eligible cycle has already been reserved or progressed. The authority either returns already_current, resumes a recoverable process, or reserves once.

Scheduled-advancement sequence

sequenceDiagram
    participant S as Primary Scheduler
    participant G as Canonical-Origin Gate
    participant A as Publication Authority
    participant DB as Authoritative Store
    participant W as Worker
    participant P as Provider

    S->>G: POST /internal/trigger<br/>signed contract + trigger_id
    G->>G: Validate trusted route, host, signature, time window
    G->>A: Submit normalized trigger
    A->>DB: INSERT trigger receipt
    A->>DB: Transaction: evaluate cycle and reserve
    DB-->>A: process_id + lease_token + revision
    A-->>S: 202 accepted / already-current
    A->>W: Dispatch resumable advance step
    W->>DB: Verify lease, release, site instance
    W->>P: Poll/fetch provider
    P-->>W: Provider result + request ID
    W->>DB: Commit state + revision + heartbeat
    W->>DB: Renew/release lease

Duplicate-trigger sequence

sequenceDiagram
    participant S1 as Primary Scheduler
    participant S2 as Fallback Scheduler
    participant A as Authority
    participant DB as Store

    par Nearly simultaneous triggers
        S1->>A: trigger T1 for cycle C
        S2->>A: trigger T2 for cycle C
    end
    A->>DB: Transaction reserve C
    DB-->>A: T1 wins; process P created
    A->>DB: Transaction reserve C
    DB-->>A: Unique cycle exists; return process P
    A-->>S1: 202 reserved P
    A-->>S2: 200 already_reserved P
    Note over A,DB: No second process or revision lineage is created

Scheduler contract

Every invocation should carry or derive the following normalized contract:

FieldPurpose and validation
contract_versionReject unsupported trigger schemas
release_idRecords the submitter’s expected release; mismatch enters doctor/status-only behavior unless explicitly compatible
site_instance_idPrevents one environment from advancing another
requested_at_utcISO 8601 UTC timestamp; enforce bounded clock skew
trigger_idGlobally unique idempotency and audit identifier
trigger_typesystemd, cron, panel_cron, cloud_http, queue, operator, synthetic
expected_canonical_originExact preconfigured origin; never copied blindly into a redirect
modeOne of status_only, doctor, or advance
maximum_runtime_secondsHard execution budget below platform termination limit
reservation_policyAcquire, resume, observe-only, or refuse when occupied
target_cycle_hintOptional hint; authority independently computes eligibility
authentication_principalVerified scheduler identity, key ID, or service account
attempt_numberDistinguishes provider retries under one trigger ID
trace_idCorrelates edge, application, worker, and provider logs

The trigger must not provide an authoritative process ID, target revision, stage, publication-success flag, or next-eligible time.

Exit-code taxonomy

For CLI and worker modes, use stable machine-readable exit codes:

CodeMeaning
0Success, including meaningful progress
10No eligible cycle; healthy no-op
11Already reserved or already complete
12Status-only or doctor completed
20Contract or release mismatch
21Site-instance or canonical-origin mismatch
22Authentication or authorization failure
30Temporary provider failure
31Temporary state-store or filesystem failure
32Lease lost or superseded
40Permanent configuration failure
41Schema or data-integrity failure
42Unsupported runtime/PHP contract
50Maximum runtime reached after checkpoint
70Unexpected internal exception

HTTP trigger acceptance should use a separate response contract. A 202 means the trigger was authenticated and recorded, not that publication succeeded.

Heartbeat record

The heartbeat should be a persisted record, not merely a log line:

{
  "site_instance_id": "prod-us-central-01",
  "release_id": "2026-08-01.3+git.ab12cd3",
  "process_id": "proc_01J...",
  "cycle_key": "daily-brief:2026-08-01",
  "trigger_id": "trg_01J...",
  "trigger_type": "systemd",
  "worker_instance_id": "host-a:pid-18420",
  "lease_token_hash": "sha256:…",
  "lease_expires_at": "2026-08-01T12:06:00Z",
  "heartbeat_at": "2026-08-01T12:05:30Z",
  "last_successful_reservation_at": "2026-08-01T12:00:02Z",
  "last_meaningful_progress_at": "2026-08-01T12:04:54Z",
  "revision": 17,
  "stage_code": "PROVIDER_WAIT",
  "next_eligible_cycle_at": "2026-08-02T12:00:00Z",
  "redacted_failure_class": null
}

A lease must expire according to the authoritative datastore’s clock, not a browser clock and preferably not a worker host clock. Renewal must compare the current lease token and process ID. Once a worker loses the lease, it must stop mutating state even if it continues running.

PHP runtime drift and deployment split-brain

Why CLI and web execution diverge

PHP reads configuration according to the invoked SAPI and startup path. The PHP manual notes that server modules generally read configuration when the server starts, whereas CLI and CGI invocations read configuration for each execution; PHP also supports additional scanned INI directories. PHP-FPM pools can set distinct users, groups, working directories, chroots, environment variables, and PHP options, and FPM’s clear_env defaults to clearing worker environments unless explicitly populated.

The CLI binary is a distinct SAPI whose location depends on installation, and multiple PHP binaries can coexist. Therefore /usr/bin/php, /usr/local/bin/php, and a hosting-provider PHP selector may represent different versions or builds.

Drift diagnostic matrix

Safe diagnostics should expose hashes and metadata, not secret values.

ConditionExpected symptomSafe diagnosticRequired evidenceRemediationRelease-proofing control
Different php.iniCLI-only errors, differing limits or extensionsCompare PHP_SAPI, php_ini_loaded_file(), scanned INI basenames and hashesCLI doctor and authenticated web doctorPin CLI with absolute binary and -c; align required settingsStore runtime-contract hash in every trigger and status
Different PHP versionsSyntax, library, TLS, or type differencesPHP_VERSION, PHP_VERSION_ID, binary realpathBoth runtimes’ doctor recordsUse same supported minor version or container/imageReject unsupported runtime contract
Different extensionsMissing database, cURL, intl, mbstring, JSON, or timezone behaviorSorted extension-name/version hashget_loaded_extensions() and selected module versionsInstall/enable same required extensionsDeployment preflight
Different environment variablesMissing endpoints, feature flags, or credentialsList approved variable names and value hashesRedacted environment manifestLoad explicit secure environment for bothNo implicit shell/login environment
Different filesystem usersPermission denied or files owned by cron userUID/GID, effective user, directory access probesstat results without contentShared group/ACL or avoid mutable release filesDedicated state directories
Different permissionsWeb can write but cron cannot, or vice versaRead/write/rename probe in dedicated diagnostic directoryOwnership, mode, ACL evidenceCorrect least-privilege ACLsPre-deploy permission test
Different temporary directoriesLocks or intermediate files never meetsys_get_temp_dir() and filesystem-device IDCLI/FPM temp paths and mount IDsUse explicit application runtime directoryNever use ambient /tmp for cross-runtime authority
Different CWDRelative includes or output paths breakgetcwd(), __DIR__, included-file rootsCLI and web path manifestschdir() only in launcher; otherwise absolute pathsBan relative production state paths
Relative paths resolve differentlyWrong config/database/cache fileResolve every configured path to canonical absolute pathPath-resolution doctor outputBuild paths from immutable application rootStatic check and startup assertion
Cron lacks web secretsProvider or database authentication failurePresence and version ID only, never secret valueSecret reference names and access resultShared secret manager or protected fileSecret-contract version check
Cron points to old releaseScheduler “works” but advances obsolete code/stateLog script realpath, release ID, inode/deviceScheduler command plus runtime release recordTarget a stable release-aware launcherLauncher refuses retired/incompatible releases
Deployment symlink changed but cron path fixedWeb new; cron oldCompare current symlink target with executed script realpathDeployment manifest and trigger recordPoint scheduler to stable launcher/current targetPost-deploy trigger doctor
Stale FPM OPcacheFiles changed but web behavior oldExpose release constant and OPcache configuration, not cache contents publiclyFPM release response before/after resetReload/restart FPM or invoke restricted FPM-side resetMandatory FPM reload and health gate
Multiple virtual hosts use different releasesHostname-dependent behaviorFetch every host and record release/site-instance headersTLS SNI, Host, origin-IP matrixOne canonical vhost; alternate hosts redirect/reject at edgeDeployment inventory and synthetic host matrix
Shared host kills long PHPProcess stops mid-stage without final statusRuntime duration and termination-class telemetryHost limit documentation and heartbeat gapShort resumable steps/queueWork units below conservative limit
Cron mail/logs discardedSilent failuresDeliberate doctor exit and stderr canaryReceipt in durable log/alert sinkCentral logs and explicit alertingDeployment blocks /dev/null 2>&1 without replacement
Web and CLI see different mounted volumesState or release differs by runtimeFilesystem device/inode IDs and sentinel file hashMount namespace and storage identityShared authoritative database/object storeSite-instance includes state-store identity

PHP’s OPcache stores precompiled bytecode in shared memory. When timestamp validation is disabled, code changes do not take effect until OPcache is reset, scripts are invalidated, or the web server is restarted. The manual also documents that CLI OPcache is disabled by default, which means a CLI-side reset is not evidence that the FPM shared cache was reset. The latter conclusion is an architectural inference from the process-specific shared-memory model and should be verified against the actual hosting setup.

Immutable-release deployment model

Use this layout conceptually:

/var/www/international-intelligence/
├── releases/
│   ├── 2026-07-28.2+git.9183abc/
│   ├── 2026-08-01.3+git.ab12cd3/
│   └── ...
├── current -> releases/2026-08-01.3+git.ab12cd3/
├── shared/
│   ├── config/
│   ├── runtime/
│   ├── logs/
│   └── uploads/
└── bin/
    └── daily-brief-launcher

The stable launcher should resolve current once, verify that the release contains a signed or hashed manifest, load that release’s bootstrap, and record the resolved realpath and release ID. It should never write process state into the release directory.

Whether cron should target current or a pinned release depends on migration compatibility:

  • For routine operation, target the stable launcher and let it resolve the active release.
  • During deployment, pause advancement briefly or use a release-compatibility gate.
  • A process already reserved under release A may continue only if release B declares its persisted-state contract compatible.
  • Otherwise, release A finishes or checkpoints before the active pointer changes.
  • The authority—not cron—decides whether a trigger from another release can resume the process.

Preventing two releases from serving one process

Each process should persist:

  • created_by_release_id
  • minimum_reader_contract
  • maximum_reader_contract, where necessary
  • writer_contract
  • site_instance_id
  • state_schema_version

A web release may display a process only if it understands its snapshot contract. A worker may mutate it only if its writer contract is permitted. This allows display compatibility without permitting two writer versions.

Release-rollout sequence

sequenceDiagram
    participant D as Deployment Controller
    participant R as New Immutable Release
    participant DB as Authority Store
    participant F as PHP-FPM
    participant C as CDN
    participant B as Browser Synthetic

    D->>R: Install dependencies and build hashed assets
    D->>R: Run offline runtime and schema compatibility checks
    D->>DB: Verify no incompatible active writer
    D->>R: Run doctor against production read-only dependencies
    D->>D: Atomically switch current symlink
    D->>F: Graceful reload / verified OPcache reset
    D->>C: Purge HTML, service-worker script, and mistaken API entries
    D->>B: Fetch canonical host with cache bypass
    B-->>D: New release + same site_instance_id
    D->>B: Run status, locale, alternate-host, and trigger synthetics
    B-->>D: Acceptance gate passes

Rollback sequence

sequenceDiagram
    participant O as Operator
    participant DB as Authority Store
    participant D as Deployment Controller
    participant F as PHP-FPM
    participant C as CDN
    participant S as Synthetic Monitor

    O->>DB: Check writer-contract compatibility
    DB-->>O: Previous release may read/write current state
    O->>D: Select previous immutable release
    D->>D: Atomically repoint current
    D->>F: Graceful reload / reset OPcache
    D->>C: Purge HTML and service-worker entry
    D->>S: Run rollback test suite
    S-->>D: Release old, site instance unchanged, revisions monotonic
    alt Prior release cannot write current schema
        O->>DB: Put advancement in safe read-only mode
        O->>D: Deploy forward-fix instead of destructive rollback
    end

Rollback must not reverse database revisions, reuse a prior process ID, or replace a new authoritative snapshot with an older snapshot. If the earlier release cannot safely understand current state, the correct rollback is read-only service plus a forward fix.

Canonical origin, cache control, and edge delivery

Canonical-origin gate

Host validation must occur before:

  • session startup;
  • cookie creation;
  • CSRF-token creation;
  • state-store selection;
  • process initialization;
  • lock or lease acquisition;
  • publication eligibility checks;
  • operator authentication side effects;
  • publication logic.

HTTP routing depends critically on the target URI’s authority or Host value. RFC 9110 warns that incorrect handling can misdirect requests and create cache-poisoning risks; servers can reject deceptive or misdirected routing with an error rather than processing it. RFC 7239 likewise warns that forwarded information can be modified by clients or intermediaries and is trustworthy only within a defined proxy trust boundary.

The gate should follow this algorithm:

  1. Obtain the connection peer address.
  2. Trust Forwarded or X-Forwarded-* only when that peer is an explicitly configured proxy.
  3. Parse exactly one effective scheme, host, and port according to the deployment’s proxy topology.
  4. Reject multiple, malformed, empty, control-character-bearing, or syntactically invalid host values.
  5. Lowercase the DNS hostname, remove a trailing dot according to policy, convert internationalized names through a consistent IDNA policy, and normalize default ports.
  6. Compare against an allowlist, never against a suffix or substring.
  7. Construct redirects from a static configured canonical origin plus the validated path and query.
  8. Do not derive the redirect destination from an untrusted host or forwarded-host value.
  9. For safe GET and HEAD, return a permanent canonical redirect.
  10. For unsafe or state-changing methods, reject the alternate-host request rather than redirecting it.
  11. Set no application cookie and initialize no state before completing this decision.

Redirect semantics

A 308 Permanent Redirect preserves the method and request content. That makes it useful for permanent canonicalization when preserving the method is intentional, but preserving an unsafe method toward another origin is precisely why the application should normally reject alternate-host POST, PUT, PATCH, and DELETE requests instead of redirecting them.

Recommended behavior:

RequestCanonical hostAlternate allowed hostUnknown or malformed host
GETProcess normally308 to static canonical origin, preserving path and query400 or 421
HEADProcess normally308, no body400 or 421
OPTIONSServe narrowly defined policy on canonical hostReject unless edge-specific CORS behavior requires otherwiseReject
POST/PUT/PATCH/DELETEAuthenticate and process421 Misdirected Request, 400, or 403; no redirectReject
Scheduler triggerRequire canonical internal route and authenticated principalReject and log security eventReject
Operator actionCanonical host onlyReject before session or authorization side effectsReject

Query strings may be preserved for safe redirects, but secrets should not be placed in query strings. The application must encode and append the existing validated request path/query; it must never accept a user-supplied full destination URL.

Alternate-host rejection sequence

sequenceDiagram
    participant U as Client
    participant E as Edge or Reverse Proxy
    participant G as Pre-Bootstrap Host Gate
    participant A as Application

    U->>E: POST https://alternate.example/operator/advance
    E->>G: Forward with normalized trusted metadata
    G->>G: Host is allowed alternate, but method is unsafe
    G-->>U: 421/400/403 + Cache-Control: no-store
    Note over G,A: No session, cookie, lock, process, or operator action

Two hostnames mapped to different roots

If www.example reaches release B while example or an old CDN origin reaches release A, application code in B cannot force A to execute B’s redirect logic. Every request to the stale origin runs whatever code and web-server configuration exist there.

Controls are therefore required outside the application:

LayerRequired control
DNSRemove obsolete origin records; keep a documented hostname inventory; use a controlled decommission period
TLS/load balancerBind all public names to one canonical edge policy; reject unknown SNI/host combinations
Reverse proxyCanonicalize or reject before PHP; avoid per-vhost document-root drift
CDNMap all aliases to the same origin pool and cache policy; block direct unintended origins
Hosting configurationOne active production document root or identical edge redirect vhosts
DeploymentEnumerate and update every vhost/origin; no undocumented manually copied roots
Synthetic monitoringProbe each hostname, with SNI and Host combinations, from multiple networks
ApplicationExpose site_instance_id and release_id so any residual split is obvious

Cache-layer map

LayerCan cause stale display?Required policy
PHP/application cacheYesStatus reads authoritative records or uses tightly invalidated in-process data
Web-server cacheYesExplicit status/operator location bypass
Reverse proxyYesNever cache status or mutation routes; do not ignore origin cache headers
CDNYesRoute-level bypass, not merely origin headers
Intermediary cacheYesStandards-compliant no-store; HTTPS reduces uncontrolled intermediary behavior
Browser HTTP cacheYesResponse no-store; fetch with cache: "no-store"
Service worker/Cache StorageYesNetwork-only for status and operator routes; never cache.put() them
Back-forward cacheYes, as restored DOM/memoryOn pageshow, fetch status before declaring live
Initial server-rendered HTMLYesLabel provisional; reconcile immediately
In-memory JavaScript stateYesMonotonic process/revision reducer
localStorageYesNotification/fallback only; never authority
BroadcastChannelYes if misusedCodes and identifiers only; recipient still validates ordering and may refetch

Service-worker Cache Storage is independent of the HTTP cache. The service-worker specification states that Cache entries do not update or expire automatically and do not disappear just because the service-worker script changes; authors must version and delete them deliberately.

Exact endpoint policies

Live public status

Recommended origin response:

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: no-store, max-age=0
Pragma: no-cache
Expires: 0
Surrogate-Control: no-store
CDN-Cache-Control: no-store
X-Site-Instance-ID: prod-us-central-01
X-Release-ID: 2026-08-01.3+git.ab12cd3
X-Snapshot-Generated-At: 2026-08-01T12:05:30Z
X-Request-ID: req_01J...

Additionally:

  • Configure an explicit edge rule to bypass cache for the status pathname.
  • Do not rely on a random query parameter as the permanent control.
  • Do not emit stale-while-revalidate or stale-if-error.
  • Normally omit ETag and Last-Modified; a 304 optimization is not valuable for a small live status document where freshness proof is more important.
  • If validators are retained for bandwidth reasons, use no-cache, private, max-age=0, must-revalidate rather than claiming that such a response is unstored. For the process-authority status, I still prefer no-store.
  • Include a response request ID and snapshot-generation timestamp so a monitor can prove origin freshness.
  • Suppress cookies from the public status endpoint.

RFC 9111 defines no-cache as a requirement to validate before reuse, not a prohibition on storage. no-store is therefore the clearer choice where a live status snapshot must not persist in shared or private HTTP caches. RFC 9111 also permits extensions and local cache configuration to affect behavior, so the CDN route must be tested and configured explicitly.

Cloudflare’s current default-cache documentation says origin cache directives are normally respected, but cache rules and edge-TTL behavior can override normal handling. Its cache-status documentation distinguishes bypassed, stale, revalidated, and cache-hit outcomes. Apache and Nginx likewise expose directives capable of changing or ignoring origin cache behavior.

Authorized operator reads

Cache-Control: no-store, private, max-age=0
Pragma: no-cache
Expires: 0
Vary: Authorization, Cookie

The endpoint must also enforce authentication, CSRF protection where cookies are used, canonical origin, and explicit method handling. private alone is insufficient because it still permits a private browser cache to store the response.

Operator and scheduler mutations

Use:

Cache-Control: no-store, private

Return an immutable trigger receipt rather than a potentially cached full status body. Require idempotency or trigger IDs.

Initial public HTML

A reasonable policy is:

Cache-Control: no-cache, max-age=0, must-revalidate

This allows storage but forces revalidation. The page must visibly indicate that embedded status is provisional until the first live API response.

Hashed JavaScript and CSS

For content-addressed filenames:

Cache-Control: public, max-age=31536000, immutable

A filename such as daily-brief.ab12cd3.js is safe to cache for a long duration because changed bytes produce another URL. This solves stale asset reuse only when every HTML document and service worker points to the new URL. It does not solve cached /api/status, because that URL and representation evolve in place.

Cache-bypassed retrieval sequence

sequenceDiagram
    participant B as Browser
    participant SW as Service Worker
    participant C as CDN
    participant R as Reverse Proxy
    participant A as Status API

    B->>SW: fetch /api/daily-brief/status<br/>cache: no-store
    SW->>C: Network-only; no Cache Storage match
    C->>C: Route-level cache bypass
    C->>R: Forward request with request ID
    R->>R: Proxy cache bypass
    R->>A: Authoritative GET
    A-->>R: no-store snapshot + generated_at
    R-->>C: no-store
    C-->>SW: BYPASS/DYNAMIC response
    SW-->>B: Unstored authoritative snapshot
    B->>B: Verify site instance, process, revision, request sequence

CDN and service-worker update strategy

For the status and operator routes:

  • CDN cache rule: bypass.
  • Worker/service-worker fetch handler: direct network fetch.
  • Cache API: no match, put, runtime fallback, or offline substitution.
  • Offline behavior: display the last accepted in-memory snapshot only with a prominent offline label and its age.
  • Error behavior: do not return an old successful status body as though it were live.
  • CDN “serve stale on error”: disabled for authority status.
  • stale-while-revalidate: disabled because it intentionally serves old data while fetching new data. Cloudflare documents that behavior as asynchronous stale delivery followed by background revalidation.

For the service-worker script itself:

  • Serve with short revalidation or no-cache, not a year-long immutable policy.
  • Use a versioned cache name tied to the release contract.
  • During activation, delete caches owned by incompatible releases.
  • Do not call skipWaiting() blindly if the new worker cannot safely control pages running old JavaScript.
  • Either coordinate activation through a “new version available” reload flow or guarantee cross-version message/API compatibility.
  • Expose the controlling service-worker version in the browser diagnostic panel.
  • Include a “network-only status route” automated test in every release.

Client convergence, status freshness, and browser behavior

Authoritative snapshot contract

Every status response should include:

{
  "schema_version": 3,
  "site_instance_id": "prod-us-central-01",
  "release_contract": {
    "serving_release_id": "2026-08-01.3+git.ab12cd3",
    "writer_release_id": "2026-08-01.3+git.ab12cd3",
    "status_contract_version": 3
  },
  "process_id": "proc_01J...",
  "target_date": "2026-08-01",
  "revision": 17,
  "stage_code": "PROVIDER_WAIT",
  "provider_state_code": "PENDING",
  "health_code": "HEALTHY_WAIT",
  "last_meaningful_progress_at": "2026-08-01T12:04:54Z",
  "last_provider_poll_at": "2026-08-01T12:05:10Z",
  "server_checked_at": "2026-08-01T12:05:30Z",
  "snapshot_generated_at": "2026-08-01T12:05:30Z",
  "next_eligible_cycle_at": "2026-08-02T12:00:00Z",
  "evidence_counts": {
    "expected": 12,
    "received": 8,
    "accepted": 7
  },
  "deficit_codes": ["PROVIDER_ITEMS_MISSING"],
  "next_action_code": "POLL_PROVIDER",
  "cache_observation": {
    "age_seconds": 0,
    "edge_status": "BYPASS"
  }
}

Localized prose should not appear in the authoritative state model. English and Spanish clients map the same codes through independent locale resources.

Reducer and ordering rules

I recommend a single reducer that applies these rules:

Incoming conditionRequired behavior
Same site instance, same process, higher revisionAccept atomically
Same site instance, same process, equal revisionNo state change; optionally update browser-only observation time
Same site instance, same process, lower revisionReject and record stale-response telemetry
Same site instance, different process with authoritative succession evidenceReplace old process atomically
Different site instanceFreeze “live” indication, show origin warning, perform hard canonical refresh
Response to older request sequenceReject even if arrival is later
Snapshot schema unsupportedShow compatibility error and reload current assets
Network failurePreserve snapshot as explicitly stale/offline; never advance it
Browser message onlyValidate identifiers; optionally request API immediately; never authorize advancement
Initial HTML onlyDisplay provisional status until API reconciliation completes

A “new process” should not be accepted merely because its process ID differs. The snapshot should carry a server-authoritative process succession relation or target-cycle ordering so a delayed response from an old origin cannot invent a replacement.

A practical ordering key is:

(site_instance_id, process_generation, process_id, revision)

process_generation should be monotonically allocated by the authority. Timestamps are supporting evidence, not the primary order, because clocks can differ and responses can be delayed.

Stale-response rejection sequence

sequenceDiagram
    participant B as Browser Reducer
    participant API as Status API

    B->>API: Request sequence 41
    B->>API: Request sequence 42
    API-->>B: seq 42, process P, revision 18
    B->>B: Accept P/18; latest_sequence=42
    API-->>B: delayed seq 41, process P, revision 17
    B->>B: Reject because sequence < 42 and revision < 18
    Note over B: DOM never regresses

Two-tab convergence

BroadcastChannel permits same-storage-key contexts to exchange structured messages, but eligible recipients must be active contexts. The HTML standard reports support across current Chromium, Firefox, and Safari generations. It remains a notification mechanism rather than persistent authority.

sequenceDiagram
    participant T1 as Active Tab
    participant API as Authority API
    participant BC as BroadcastChannel
    participant T2 as Background Tab

    T1->>API: GET authoritative status
    API-->>T1: P/revision 18
    T1->>T1: Validate and accept
    T1->>BC: {site, process, revision, stage_code}
    BC-->>T2: Notification
    T2->>T2: Validate identifiers
    alt Payload is newer than local state
        T2->>API: Read-only confirmation fetch
        API-->>T2: P/revision 18
        T2->>T2: Accept authoritative snapshot
    else Equal or older
        T2->>T2: Ignore/no-op
    end

The fallback is a localStorage notification key whose value contains only a random event ID plus process/revision identifiers. The storage standard dispatches events to equivalent storage contexts, but it also explicitly warns that local storage has no general locking mechanism and can fail or be disabled by policy. It must not generate unique process IDs or coordinate publication locks.

English and Spanish convergence

sequenceDiagram
    participant EN as English Client
    participant ES as Spanish Client
    participant API as Status API
    participant BC as Cross-Tab Channel

    EN->>API: GET /api/status
    ES->>API: GET /api/status
    API-->>EN: P/18, stage_code=PROVIDER_WAIT
    API-->>ES: P/18, stage_code=PROVIDER_WAIT
    EN->>EN: Render "Waiting for provider"
    ES->>ES: Render localized Spanish label
    EN->>BC: P/18 + codes only
    BC-->>ES: P/18 + codes only
    ES->>ES: Equal revision; no authoritative state change
    Note over EN,ES: Identical process and revision; locale prose is independent

Status-freshness model

A PID or process ID must never by itself produce a green “live” state.

Timestamp or valueMeaningUI use
last_meaningful_progress_atLast durable stage/evidence/revision advancementPrimary stall detector
last_provider_poll_atLast attempted provider observationShows polling activity, not progress
heartbeat_atLast worker lease heartbeatShows worker liveness
server_checked_atTime authority evaluated healthShows recency of server decision
snapshot_generated_atTime JSON was serializedHelps identify replayed/cached bodies
HTTP Age or CDN cache metadataTime held by an intermediaryMust be zero/absent for live status
Browser received_atLocal time response arrived“Checked moments ago” only
Browser offline_sinceStart of known connectivity lossProminent offline-age label
next_eligible_cycle_atEarliest expected next process cyclePrevents normal idle periods appearing broken
health_codeServer-derived health based on stage-specific thresholdsPrimary status category

Suggested server health states:

Health codeMeaning
IDLE_NOT_ELIGIBLENo cycle should be running yet
HEALTHY_PROGRESSMeaningful progress within stage-specific threshold
HEALTHY_WAITWaiting is expected and recent provider polling/heartbeat exists
DEGRADED_NO_PROGRESSWorker is alive but progress threshold exceeded
STALE_HEARTBEATProcess owns a lease but heartbeat is late
LEASE_EXPIRED_RECOVERABLEPrevious worker lost ownership; another trigger may resume
BLOCKED_DEFICITRequired evidence remains missing
FAILED_RETRYABLETemporary failure and retry policy exists
FAILED_PERMANENTOperator intervention required
ORIGIN_MISMATCHSite-instance or release contract is inconsistent
OFFLINE_CLIENTBrowser-only display condition, not a server health code

Stage-specific thresholds matter. Ten minutes without a revision may be normal while waiting for a provider but abnormal during a local render stage expected to last seconds.

Browser compatibility and throttling

Background execution cannot be treated as a scheduler. Chromium documents intensive timer throttling for qualifying long-hidden pages, with timers checked on a much coarser cadence; request-animation callbacks also stop in background pages. WebKit documents background timer throttling and notes that iOS can suspend background tabs completely. Firefox likewise manages or unloads background tabs under resource pressure.

Capability or behaviorChromium familyFirefoxSafari macOSSafari/iOSRequired design
BroadcastChannelSupportedSupportedSupported in current releasesSupported in current releasesFeature-detect; storage-event fallback
Background timersAggressively throttled after qualifying hidden periodsThrottled; background lifecycle is resource-sensitiveThrottledMay be suspended entirelyHidden tabs use low-frequency best-effort polling
requestAnimationFrame in backgroundPausedGenerally pausedPausedPaused/suspendedNever drive polling from animation frames
Tab unloading/discardPossiblePossiblePossibleCommon under memory pressureTreat resume as cold reconciliation
Service workerSupportedSupportedSupportedSupported with platform lifecycle constraintsNetwork-only status route; versioned cache cleanup
Back-forward restorationSupportedSupportedSupportedSupportedHandle pageshow; refetch when restored
localStorage eventsBroad supportBroad supportBroad supportBroad supportNotification only; catch access exceptions
Private browsingStorage/persistence constraints can differConstraints can differConstraints can differConstraints can differFeature-detect and continue without persistence
Online/offline eventsAvailable but not proof of origin reachabilitySameSameSameConfirm with actual status request
Multiple windowsSupportedSupportedSupportedLimited by mobile UI/lifecycleAPI remains authority
Orientation changesNo authority effectNo authority effectNo authority effectCan accompany suspension/layout changesRe-render, but do not mutate process state

WHATWG defines pageshow.persisted so a page can detect restoration from retained session history rather than a fresh load. On every pageshow, and especially when persisted is true, the client should immediately mark the DOM provisional and fetch authoritative status.

Fallback protocol

The client should:

  1. Fetch immediately after page initialization.
  2. Refetch on visibilitychange when a page becomes visible.
  3. Refetch on pageshow, including back-forward-cache restoration.
  4. Refetch after a successful network reconnection.
  5. Keep a low-frequency, jittered, read-only poll while hidden when the browser permits.
  6. Expect missed hidden polls and reconcile on resume.
  7. Use BroadcastChannel as the preferred wake-up hint.
  8. Use the storage event as a fallback wake-up hint.
  9. Use neither mechanism to create process state or invoke advancement.
  10. Abort superseded requests where possible and still enforce sequence/revision checks.
  11. Display “offline” or “status unavailable” when no current authoritative response exists.
  12. Never solve throttling merely by reducing the polling interval; browsers may coalesce or suspend it regardless.

Production testing, deployment, and rollback controls

Synthetic test matrix

Every synthetic response should record DNS answer, TLS certificate/SNI, resolved origin, HTTP status, redirect chain, release ID, site-instance ID, request ID, cache status, Age, snapshot time, process ID, and revision.

TestMethodExpected resultFailure isolated
Canonical public pageGET canonical English and Spanish pagesSame site instance and releaseLocale/vhost split
Alternate-host safe requestGET each aliasOne 308 to configured canonical origin; path/query preservedEdge canonicalization
Alternate-host mutationAuthenticated test POST with no effectRejected without cookie, session, trigger, or lockLate host enforcement
Unknown HostDirect edge/origin probe where authorized400/421, never default vhostHost-routing weakness
Status freshnessRepeated status requestsno-store; zero/absent Age; advancing request IDs/timestampsBrowser/CDN/proxy cache
Cache-busted pairOrdinary and unique diagnostic querySame authoritative revision and fresh generation timeHidden cache or cache-key issue
Service-worker clean profileNew browser profileSame status as established profileStale worker/cache
Service-worker bypassBrowser with worker bypassedSame authoritative resultWorker interception
CLI doctorScheduler runtimeExpected PHP, INI, extension, UID, CWD, release, site instancePHP drift
Web doctorAuthorized web runtimeContract matches CLI where requiredFPM drift
Scheduler canaryStatus-only triggerTrigger receipt and heartbeat, no publication mutationScheduler delivery
Duplicate triggerTwo trigger IDs for one cycleOne process and revision lineageIdempotency
Lease-expiry recoveryControlled test process stops renewingNew worker resumes only after expiryPermanent lock
Delayed-response raceArtificially delay older status responseUI never regressesClient reducer
Background resumeHide/suspend tab, progress server, resumeImmediate reconciliationTimer dependency
Back-forward restoreNavigate away/back after server progressProvisional state then current API statebfcache staleness
Cross-localeOpen English and Spanish simultaneouslySame process/revision/codesLocalized-state divergence
Cross-host processQuery every public hostnameNo different site instance or process lineageRoot/origin split-brain
FPM OPcacheDeploy release canaryWeb response changes only after verified reload gateStale bytecode
RollbackControlled prior releaseSite instance unchanged; revisions do not decreaseUnsafe rollback
DST simulationTest eligibility around spring/fall transitionsExactly one cycle per target dateLocal-time scheduling bug
Separate filesystem sentinelCLI/web read same read-only sentinel hashIdentical identityMount split
CDN stale-on-errorControlled nonproduction origin failureStatus becomes unavailable, not falsely liveEdge stale serving
Offline browserDisable networkExplicit offline label and increasing offline ageStale snapshot masquerading as live

Scheduled-trigger acceptance checks

A scheduler test is not complete when the scheduler reports an HTTP 2xx. The monitor must correlate:

scheduler execution
→ trigger receipt
→ reservation result
→ heartbeat
→ meaningful revision or healthy no-op
→ status API visibility
→ browser-facing synthetic visibility

Alert separately on:

  • no scheduler execution;
  • execution without receipt;
  • receipt without reservation decision;
  • reservation without heartbeat;
  • heartbeat without meaningful progress;
  • authoritative progress not visible at the canonical status endpoint;
  • canonical endpoint current but browser synthetic stale.

This decomposition identifies the failing layer rather than reporting only “Daily Brief broken.”

Deployment checklist

PhaseRequired control
BuildImmutable release ID, dependency lock, asset manifest, status-contract version
PreflightCLI and FPM compatibility, required extensions, schema compatibility, path and permission checks
InstallNew release directory only; no in-place edits to current release
State gateConfirm compatible active processes or pause/resume strategy
SwitchAtomic pointer or load-balancer target change
PHPGraceful FPM reload or verified FPM-side OPcache invalidation
SchedulerDoctor invocation resolves intended launcher and active release
CDNEnsure API bypass; purge HTML, service-worker script, and accidentally cached API objects
Service workerVerify script update, cache version, activation compatibility, network-only status route
Canonical hostsProbe all aliases and direct-origin paths permitted to monitors
BrowserClean and established profiles; English and Spanish; multiple tabs
AcceptanceSite-instance stable, release expected, status fresh, duplicate trigger idempotent
Rollback readinessPrior immutable release retained and compatibility result known
ObservationMonitor at least one complete advancement cycle with correlated trace IDs

Rollback checklist

A rollback should:

  • stop new incompatible writers;
  • retain the authoritative database and monotonic revision history;
  • atomically restore the previous compatible release;
  • reload FPM;
  • purge affected HTML and service-worker entry points;
  • leave hashed assets immutable;
  • verify scheduler launcher resolution;
  • run canonical-host, status, locale, and duplicate-trigger tests;
  • resume advancement only after writer-contract compatibility is established.

Do not delete or “reset” the current process merely to make an older release appear healthy. Preserve the process record and use an explicit supersession or recovery transition.

Remediation roadmap, uncertainties, acceptance criteria, and reading list

Prioritized remediation roadmap

PriorityActionWhy firstEvidence of completion
ImmediateAdd site_instance_id, serving release, writer release, status contract, snapshot time, request ID, and cache observation to status responsesMakes split-brain and stale delivery visibleEvery hostname returns traceable identity
ImmediateEnforce no-store plus explicit CDN/reverse-proxy/service-worker bypass on status and operator routesCached authority state is a direct correctness failureMulti-region synthetics show no cache hits or Age
ImmediateCreate authenticated CLI and web doctor reportsQuickly exposes PHP, path, secrets, and mount driftContract diff is empty or explicitly approved
ImmediateVerify scheduler existence, next run, command, PHP binary, release path, logs, and exit captureInternal tests cannot substitute for production schedulingTrigger trace from scheduler to authority
ImmediateMake reservation transactional, expiring, token-bound, and datastore-clock-basedPrevents duplicate work and permanent locksDuplicate and lease-expiry tests pass
HighImplement monotonic browser reducer with request sequence rejectionPrevents visual regression despite correct server stateArtificial delayed-response test passes
HighMove canonical-origin enforcement before PHP application bootstrap where possiblePrevents alternate-host state side effectsUnsafe alias requests create no cookie or record
HighConsolidate all vhosts/CDN origins onto one document root/site instanceEliminates stale-origin split-brainHost inventory and synthetic matrix agree
HighAdopt immutable release directories and FPM reload gateEliminates in-place deploy and OPcache ambiguityRollout reports exact release through web and CLI
HighAdd stage-aware health based on meaningful progress and heartbeatPID alone is misleadingUI distinguishes waiting, stalled, offline, and failed
MediumUse primary scheduler plus delayed independent fallbackImproves trigger availabilityPrimary-loss exercise still reserves one process
MediumConvert long advancement to resumable work unitsReduces host runtime-limit riskForced termination resumes without duplication
MediumVersion and audit service-worker cachesEliminates long-lived client split-brainEstablished-profile upgrade test passes
MediumSchedule in UTC and test publication-date computation over DSTEliminates ambiguous wall-clock executionSpring/fall simulations create one cycle
OngoingRun post-deploy and periodic production syntheticsDetects regressions outside application testsAlerting tied to each layer’s contract

Key uncertainties and evidence gaps

The most important unresolved questions are:

GapWhy it mattersMinimum evidence needed
Is any scheduler installed and enabled?Without it, no autonomous advancement occursScheduler configuration and last execution
Which release does it invoke?Old code may update incompatible or invisible stateExecuted script realpath and release ID
Do CLI and FPM share the same state store?Both can appear healthy while observing different worldsRedacted datastore identity hash
How many public origins/document roots exist?An old origin can evade current application redirectsDNS, CDN, LB, vhost, and document-root inventory
Is status cached at the edge?Browser may never see progressEdge rule export and synthetic cache evidence
Is a service worker registered?It can intercept despite correct HTTP headersRegistration, scope, script version, cache names
What is the lease implementation?A stale lock may block every valid triggerLease token, owner, expiry, renewal history
What is the cycle timezone rule?DST and date-boundary errors can look intermittentIANA timezone and UTC eligibility examples
Are English and Spanish separate deployments?Locale-specific roots may divergeRelease/site-instance headers on both
Is browser status acceptance monotonic?Delayed responses can visually undo progressClient telemetry or controlled race test

Acceptance criteria

Production should not be declared reliable until all of the following are true:

Scheduler and authority

  • At least one production scheduler is demonstrably enabled.
  • Every run supplies a unique trigger ID and UTC timestamp.
  • Every trigger receipt records trigger type, authenticated identity, expected origin, release, and site instance.
  • Duplicate triggers for the same cycle create exactly one process lineage.
  • Locks are expiring leases with token-bound renewal.
  • A stopped worker becomes recoverable after a bounded expiry.
  • The external scheduler cannot set process ID, revision, stage, success, or next cycle.
  • Scheduler 2xx acceptance is not confused with publication completion.
  • UTC cadence and local publication-date calculation pass both DST-transition simulations.

Runtime and deployment

  • CLI and FPM report approved PHP versions, INI contracts, extensions, paths, secrets references, site instance, and state-store identity.
  • Scheduler commands use absolute paths.
  • No production state depends on the current working directory or ambient temporary directory.
  • Releases are immutable and identified in every trigger and response.
  • The active release switch is atomic.
  • FPM OPcache reset or reload is verified in the FPM runtime.
  • Scheduler and web execution resolve a compatible release.
  • Rollback preserves monotonic revisions and process identity.
  • Two releases cannot concurrently mutate one process unless explicitly writer-compatible.

Origin security

  • Canonical-host validation runs before cookies, sessions, locks, state, and authorization side effects.
  • Safe alternate-host requests receive a deterministic canonical redirect.
  • Unsafe alternate-host requests are rejected.
  • Redirect destinations are constructed from static configuration.
  • Forwarded hosts are trusted only from explicit proxy addresses.
  • Malformed and unknown hosts never reach the normal application.
  • All hostnames and origin paths resolve to one site instance or to an edge-level rejection/redirect.

Cache and CDN

  • Public status and operator endpoints return Cache-Control: no-store.
  • Reverse proxies and CDNs have explicit route-level bypass rules.
  • Status responses do not use stale-while-revalidate or stale-if-error.
  • CDN failure does not turn an old status into apparently live status.
  • Browser fetches use cache: "no-store".
  • The service worker uses network-only handling for status and mutation routes.
  • Cache Storage contains no status or operator responses.
  • Query-string cache busting is diagnostic only, not the primary policy.
  • Hashed assets are immutable and HTML/service-worker entry points are revalidated.

Browser convergence

  • Initial HTML is labeled provisional until an API response arrives.
  • Same-process lower revisions are rejected.
  • Equal revisions are no-ops except for browser-only observation times.
  • A new process replaces the prior snapshot atomically.
  • Different site-instance IDs force a visible warning and origin refresh.
  • Older request sequences cannot overwrite newer responses.
  • Background tabs reconcile on visibility and page restoration.
  • Offline state is unmistakably labeled with offline age.
  • BroadcastChannel and local storage cannot authorize or advance work.
  • English and Spanish render the same codes and identifiers with independent localized strings.
  • A process ID without recent meaningful progress does not produce a live indicator.

Observability

  • The status UI separately displays meaningful progress, provider poll, server check, snapshot generation, browser check, cache age, and offline age.
  • Every layer can be correlated through trigger, trace, request, process, release, and site-instance identifiers.
  • Scheduler output and errors are retained outside transient cron mail.
  • Synthetic monitoring covers every public hostname, both languages, clean and established browser profiles, cache bypass, background restoration, and duplicate triggers.
  • Post-deploy checks block rollout completion when identity, freshness, or convergence contracts fail.

Prioritized official reading list

PrioritySourceWhy it mattersURL
EssentialRFC 9111, HTTP CachingNormative definitions of no-store, no-cache, private/shared cache, validation, Age, Vary, and stale reusehttps://www.rfc-editor.org/rfc/rfc9111.html
EssentialRFC 9110, HTTP SemanticsHost/authority routing, safe and unsafe methods, redirects, 308 behavior, and misdirected requestshttps://www.rfc-editor.org/rfc/rfc9110.html
EssentialRFC 7239, Forwarded HTTP ExtensionTrusted-proxy and forwarded-header security considerationshttps://www.rfc-editor.org/rfc/rfc7239.html
EssentialPHP configuration-file documentationPHP configuration discovery and SAPI startup behaviorhttps://www.php.net/manual/en/configuration.file.php
EssentialPHP-FPM configurationPool users, environments, working directories, output handling, and PHP optionshttps://www.php.net/manual/en/install.fpm.configuration.php
EssentialPHP OPcache configurationTimestamp validation, CLI OPcache, path keys, and required resetshttps://www.php.net/manual/en/opcache.configuration.php
Essentialsystemd timer manualCalendar timers, persistence, accuracy, and timer activationhttps://www.freedesktop.org/software/systemd/man/latest/systemd.timer.html
Essentialsystemd execution environmentUsers, working directories, environment, credentials, logging, and process executionhttps://www.freedesktop.org/software/systemd/man/latest/systemd.exec.html
Highcrontab manualCron fields, timezone handling, environment, and implementation caveatshttps://man7.org/linux/man-pages/man5/crontab.5.html
HighcPanel Cron JobsShared-host scheduling, absolute paths, overlap warning, and cron mail behaviorhttps://docs.cpanel.net/cpanel/advanced/cron-jobs/
HighGoogle Cloud Scheduler troubleshootingDuplicate delivery, idempotency, logs, retries, and UTC/DST guidancehttps://cloud.google.com/scheduler/docs/troubleshooting
HighAWS EventBridge SchedulerAt-least-once delivery, retries, flexible windows, and target behaviorhttps://docs.aws.amazon.com/scheduler/latest/UserGuide/what-is-scheduler.html
HighWHATWG BroadcastChannelSame-origin/storage-key messaging semantics and active-context eligibilityhttps://html.spec.whatwg.org/multipage/web-messaging.html#broadcasting-to-other-browsing-contexts
HighWHATWG Web StorageStorage-event behavior, failure conditions, and absence of locking guaranteeshttps://html.spec.whatwg.org/multipage/webstorage.html
HighW3C Service WorkersCache Storage lifetimes and manual cache versioninghttps://www.w3.org/TR/service-workers/
HighWHATWG navigation and historypageshow, persisted-page restoration, and history lifecyclehttps://html.spec.whatwg.org/multipage/nav-history-apis.html
HighPage Visibility specificationReliable visibility-state observation for resume reconciliationhttps://www.w3.org/TR/page-visibility-2/
SupportingNginx proxy moduleProxy cache controls and origin-header override behaviorhttps://nginx.org/en/docs/http/ngx_http_proxy_module.html
SupportingApache mod_cacheReverse-proxy cache operation and administrative overrideshttps://httpd.apache.org/docs/2.4/mod/mod_cache.html
SupportingCloudflare default cache behaviorCurrent edge defaults and interaction with origin cache headershttps://developers.cloudflare.com/cache/concepts/default-cache-behavior/
ResearchHidden Web Caches Discovery, 2024Empirical technique for identifying caches that do not clearly advertise themselveshttps://arxiv.org/abs/2407.16303
ResearchThe Remote on the Local, 2021Security implications of programmable service-worker cacheshttps://doi.org/10.1109/SPW53761.2021.00062

The architectural endpoint is not “poll more often.” It is a system in which every layer can prove that it is observing the same site instance, compatible release, process lineage, revision, and authoritative state—and in which a scheduler, cache, alternate host, old service worker, suspended tab, or delayed response can fail without manufacturing a false picture of publication health.