# Static File Engine

Choose dynamic delivery, essential compatibility files, or full eligible static publication.

Choose dynamic delivery, essential compatibility files, or full eligible static publication.

## How it works

Dynamic WordPress handlers are always the routing baseline. The Static File Engine is an optional materialization layer:

Dynamic responses include Cybermaps-managed CORS, ETag, Content-Digest, Repr-Digest, X-Robots-Tag, CSP, and RFC 9111-oriented cache-policy headers. When a physical copy is served directly, PHP does not receive the request, so the web server or CDN must add any equivalent headers required by the deployment.

| Mode | Physical publication |
| --- | --- |
| `off` | No generated files; supported requests use WordPress when the server routes them to PHP |
| `well_known` | Up to 11 small registered root, discovery-index, and canonical well-known targets, limited to enabled capabilities; this is the default |
| `all` | The sitemap index and internal children, enabled RSS output, protocol-safe discovery files, localized LLMS output, and eligible RAG chunks |

The default target inventory is:

Quick Setup can select a different mode: activity insights choose `off`, while lightweight delivery chooses `all`. The default above applies before that preset or another administrator setting is applied. Multisite always resolves to `off`.

1.  `/ai.json`
2.  `/ai-usage.json`
3.  `/ai-actions.json`
4.  `/.well-known/agent-skills/cybermaps-site-guide/SKILL.md`
5.  `/.well-known/agent-skills/index.json`
6.  `/.well-known/api-catalog`
7.  `/.well-known/ai-catalog.json`
8.  `/.well-known/mcp/server-card.json` when MCP is enabled
9.  `/.well-known/oauth-authorization-server` when MCP is enabled
10.  `/.well-known/oauth-protected-resource` when MCP is enabled
11.  `/ai-discovery`

Dynamic routing remains preferred because it controls protocol headers, media types, throttling, and PHP-side request observations. Some nginx and OpenLiteSpeed configurations intercept `/.well-known/` before WordPress. The ownership-safe physical fallbacks make canonical bodies available in that environment when the root is writable and the server serves those files. `/ai-discovery` is also materialized. Writing a correct physical file does not invalidate a cached response already held by nginx or another proxy. An extensionless static API Catalog may still receive a generic media type from the origin; Cybermaps therefore reports availability and body validity separately from RFC 9727 header conformance and never labels the wrong media type conformant.

`/skill.md` remains a dynamic compatibility URL. The canonical nested `SKILL.md` can be materialized, but `.md` alone does not guarantee a server will send `text/markdown`; dynamic fallback returns the registered `text/markdown` response when the request reaches WordPress.

On a subdirectory WordPress installation, Cybermaps derives the origin document root conservatively. A differently rooted or remote headless frontend must provide the `cybermaps_static_publication_root` filter. Multisite is dynamic-only so individual sites never compete for shared root filenames.

### Write safety and reconciliation

Static writes use `WP_Filesystem`, a temporary file, a verified move, and a recorded content hash. Cybermaps overwrites or deletes a path only while the current bytes still match its ownership record. Pre-existing or edited files are retained and reported as conflicts.

When WordPress receives a valid request for an active static target that is missing or unreadable, Cybermaps serves the dynamic representation for that request and queues the existing coalesced background reconciliation. The same repair check covers valid sitemap children and the RSS sitemap in `all` mode. It is disabled in `off` mode and on multisite, and never bypasses ownership verification.

Full sync, purge, ownership migration, and static-file mutations use an installation-local option lease plus a connection-scoped MySQL/MariaDB advisory lock acquired through WordPress Core’s `wpdb` connection. Lease renewal, release, ownership-shard changes, and write-intent changes compare the exact observed database value and prove the same advisory-lock owner and connection in the mutation statement. A request that loses or reconnects its database session fails the static mutation closed and queues reconciliation; dynamic publication remains available. Database drop-ins that replace the exact Core `wpdb` class or may route statements across different connections are unsupported for static mutation.

Immediately before a file move or ownership-verified deletion, Cybermaps stores one durable typed intent containing the normalized path, prior ownership evidence, intended outcome, generation, epoch, and a digest of the active lease. The operation revalidates the exact journal row, option lease, and database fence at the last portable boundary before changing the filesystem. Recovery adopts only an exact recorded outcome; any third-party body is retained as a conflict.

A pending intent blocks automatic takeover of a stale option lease. That is intentional: WordPress has no portable compare-and-move or compare-and-delete primitive that can fence a disconnected but paused PHP process. The settings screen exposes an exceptional recovery action for a valid journal. It requires `manage_options`, an intent-bound nonce, and an exact typed confirmation that all Cybermaps web, cron, and CLI static workers have been stopped or quiesced. A malformed journal remains untouched for support review. This protocol makes interrupted transitions diagnosable and recoverable without pretending that a database transaction and a filesystem mutation are one atomic cross-resource transaction.

The CYBERMAPS data upgrade uses a separate exact compare-and-swap option lease. It reloads migration state after acquiring that lease, and each production state, data-version, or coordination-state mutation compares both the exact observed target value and the exact current lease row in the same database statement. A worker that loses its lease cannot overwrite a successor’s checkpoint. Fresh activation uses that same lease and an insert-only version checkpoint, and it refuses to stamp an installation that already has configuration or any upgrade coordination state.

The shared translation-registry schema is independently monotonic and uses a target-owned coordination record plus a database-session fence. Its schema, state, and cleanup mutations compare exact observed values while that fence is held, so an older release cannot downgrade a future schema or erase a future retry. The physical shared-table migration uses one installation-wide fence; site-option coordination remains network-specific. A database drop-in that cannot provide the required Core connection-bound fence defers only the sharded static-ownership migration with bounded retry state; unrelated 6.1.0 migrations, the data-version checkpoint, and dynamic publication continue normally.

A full synchronization has deterministic write and wall-clock ceilings. When a large sitemap or chunk inventory crosses either ceiling, Cybermaps checkpoints its non-autoloaded continuation state and ownership inventory, schedules the next run, and revalidates completed files against their ownership hashes before skipping their expensive generators. A settings or content mutation advances the generation fence and discards obsolete continuation progress.

LLMS static publication uses the same output ceilings as dynamic delivery: 4 MiB minus 1 byte (4,194,303 bytes) for `/llms.txt`, and 32 MiB minus 1 byte (33,554,431 bytes) for `/llms-full.txt`, including localized variants. Available PHP memory can impose a lower limit. These are output ceilings, not cache-storage thresholds. Generation completes or fails without silently truncating the corpus; static reconciliation records `publication_too_large` instead of writing a partial file. Dynamic requests exceeding an applicable output or memory-headroom limit return HTTP 507 with `application/problem+json`. These limits already existed in v7.4.1; see the [documentation correction and tagged source references](https://cybermaps.dev/docs/machine-publications/#llms-output-ceilings).

When complete LLMS generation exceeds its applicable limit, reconciliation first attempts to remove the prior file only if its current bytes still prove Cybermaps ownership. Because `WP_Filesystem` offers whole-string reads rather than portable streaming hashes, an unusually large legacy file beyond the separate bounded verification limit is retained and reported instead of being read into memory or deleted without proof.

Children are written before their indexes. Reconciliation reports distinguish desired, written, unchanged, conflicted, failed, skipped, deleted, and retained targets. A successful timestamp advances only after the selected inventory finishes successfully.

Changing from `all` to `well_known` removes eligible Cybermaps-owned web-root files while retaining the active well-known set. Changing to `off` removes eligible Cybermaps-owned files. **Regenerate Publications** clears applicable caches and performs an immediate active-mode sync; **Static File Cleanup** purges ownership-verified generated files.

### Cache and edge integration

The **Debugging** submenu reports availability and Cybermaps utilization as separate facts. An installed Redis drop-in is reported as active only when WordPress exposes a persistent object cache; an available APCu or LiteSpeed integration is reported as unused when its independent Advanced opt-out is disabled. The copied diagnostic report excludes tokens, credentials, network addresses, cookies, and filesystem paths.

Advanced settings use Cloudflare’s public OAuth Authorization Code flow with PKCE to install or repair up to four enabled response-header profiles, an origin query rewrite, and a cache-safety rule. The administrator chooses the owning account and authorizes only Zone Read, Zone Transform Rules Write, and Cache Settings Write. WordPress holds the verifier, exchanges the code directly, performs the bounded Rulesets operations, attempts to revoke the access token, and discards it. A failed revocation is reported separately; Cybermaps does not retain a reusable token.

The origin rewrite applies only to GET/HEAD requests for `/ai-discovery` on the configured hostname with an empty query string. It adds `cybermaps_origin={plugin-version}-{hostname-hash}` to the origin query while preserving the public URL. Existing query strings are excluded. This avoids an older cache entry only when the origin uses query strings in its cache decision; it cannot fix every proxy configuration. The rule is included in combined OAuth installation, owned-rule removal, and drift fingerprints. Reauthorize after a release or configuration change that changes the expected rules. A recorded fingerprint is not a live Cloudflare configuration audit.

Installation checks enabled discovery bodies before applying response-header rules. A 404 or invalid body blocks that step: changing response headers does not create a missing origin resource. Regenerate Publications and inspect the per-path delivery results first. The number of resource checks follows enabled publications and is different from the number of Cloudflare rules or buttons.

The fixed [https://connect.cybermaps.dev/cloudflare/callback](https://connect.cybermaps.dev/cloudflare/callback) relay stores an unusable authorization code for at most five minutes. It never receives the verifier, access token, WordPress identity, site URL, or rule payload. Its source is shipped under infrastructure/cloudflare-oauth-relay/ in the development repository and excluded from the WordPress.org plugin artifact. Accounts that disable public OAuth can use either site-local self-managed OAuth or the retained one-time-token fallback. Self-managed mode uses a secretless client with response type `code`, grant type `authorization_code`, token authentication method `none`, PKCE `S256`, and the site’s exact `/wp-admin/admin-post.php?action=cybermaps_cloudflare_oauth_callback` URL. Cloudflare returns directly to WordPress, the relay is bypassed, and only the public client ID is stored. The required scopes are exactly `zone.read`, `zone-transform-rules.write`, and `cache-settings.write`. Cybermaps records only non-secret zone, owned-rule, fingerprint, and credential-disposal metadata so Debugging can report drift without maintaining a connection.

The one-time-token fallback currently exposes separate header and cache-safety installation buttons, plus removal. Those install buttons do not call the combined OAuth installation and do not install its origin query rewrite. Use managed or self-managed OAuth for that complete flow. The API token is used directly by WordPress for the requested operation and is not saved.

Diagnostic logging is disabled by default. Administrators can enable it for one, four, or 24 hours while reproducing a problem. Cybermaps stores at most 200 events in non-autoloaded site options and automatically stops collection when the selected window expires. Events older than seven days are discarded. Support bundles combine the secret-free system report with recent redacted events. They omit credentials, cookies and headers, request bodies, crawler analytics, IP and email addresses, full URLs, and absolute paths.

After Cloudflare confirms a rule mutation, the Advanced page verifies every eligible discovery resource from the administrator’s browser. This avoids false failures caused by blocked or split-DNS server loopbacks, retries briefly for edge propagation, and reports each failing path with its HTTP, body, and header result. A short-lived terminal OAuth result also survives a missed AJAX response or page reload; it contains no credential.

Before presenting any mutation as available, Cybermaps checks the exact configured public hostname for Cloudflare proxy traffic using the current request and a fresh browser probe. Undetected sites keep OAuth and API-token mutation controls disabled. Split-DNS, headless, or header-stripping deployments can use an explicit page-scoped confirmation naming that hostname; the override is not persisted and does not bypass authorization, scopes, zone selection, or post-install verification.

Cybermaps keeps its internal publication, registry, route, and diagnostic cache entries in generation-fenced WordPress Cache API groups. A content or settings change advances the relevant generation, so stale values fall out without requiring a broad object-cache flush. Keys include the blog ID and a hash of the WordPress site URL and `WP_CACHE_KEY_SALT`, with a filesystem-root fallback when the site URL is unavailable. Independent installations therefore do not collide solely because both have blog ID 1. This protects Cybermaps’ keys; it does not configure another plugin’s cache or the web server’s cache key. If the site provides a conforming `object-cache.php` drop-in backed by Redis or Memcached, Cybermaps uses it automatically through WordPress Core APIs. There is no Redis or Memcached client dependency in the plugin, and those stores are treated as acceleration, not as durability authorities.

When the APCu extension is available and the administrator enables Cybermaps’ APCu layer, it stores disposable derived values. Cybermaps reads APCu only for keys populated during the current request; it does not use an older APCu value as the authority for a fresh request. Its installation namespace also applies to APCu keys. The plugin makes no assumption that APCu memory is isolated per PHP worker, and never uses it for queues, locks, ownership proofs, or recovery state. The Advanced APCu and LiteSpeed integration controls are independently enabled by default but require their respective runtime dependencies.

IndexNow durability is database-backed. Enabled submissions enter a typed queue with same-host deduplication, retry metadata, and bounded batch construction. Object caches can make queue reads faster, but the queue authority remains the database.

LiteSpeed integration is automatic when the LiteSpeed Cache for WordPress plugin exposes its public purge/tag hooks and the integration remains enabled. Cybermaps adds Cybermaps-specific tags to compatible dynamic responses and asks LiteSpeed to purge affected publication URLs after relevant content, settings, static-publication, or IndexNow state changes. Without that plugin, LiteSpeed servers still receive the same dynamic/static Cybermaps responses but no LiteSpeed-specific purge is attempted.

Negotiated canonical pages require request-time cache separation. Cybermaps marks Markdown responses that reach PHP non-cacheable through LiteSpeed’s documented API and purges LiteSpeed page objects when the feature changes, but an existing server cache can answer before PHP. LiteSpeed/OpenLiteSpeed sites must therefore bypass cache lookup for requests whose `Accept` field contains `text/markdown`, for example with an operator-reviewed Apache-compatible rule:

```
RewriteCond %{HTTP:Accept} text/markdown [NC]
RewriteRule .* - [E=Cache-Control:no-cache]
```

nginx and Varnish should retain `Vary: Accept`; operators may normalize Accept to HTML versus Markdown to avoid unbounded cache variants. Cloudflare’s own Markdown for Agents feature may supply the edge representation instead. A remote headless frontend must proxy negotiation or implement it at that frontend because its canonical requests do not reach WordPress.

Varnish support is deliberately opt-in and exact-URL only. When configured, Cybermaps can send protected PURGE requests for known Cybermaps publication URLs. The operator must configure Varnish ACLs, method handling, and any required secret/header validation. Cybermaps does not claim portable nginx purge support, because nginx purge behavior depends on non-standard modules or CDN-specific APIs.

The Advanced diagnostics provide advisory snippets for nginx, Apache, OpenLiteSpeed, Varnish, and common CDN edge rules. These snippets describe MIME types, routing exclusions, cache policy, validators, Repr-Digest/header parity, and exact Cybermaps paths. These snippets are advisory; the owned origin rewrite block and explicitly authorized Cloudflare rule operations described above are the automatic exceptions. Diagnostics also report active integration settings, relevant runtime constants, and the WordPress hooks or filters that are active or unavailable in the current installation. Public extension points remain WordPress-native, including `cybermaps_static_publication_root` for alternate static roots and `cybermaps_client_ip_resolution` for validated proxy integrations.

## Concurrent builds and retries

Cold LLMS builds share a site- and publication-specific ownership lock across dynamic, REST, localized, and forced/static generation. A competing request serves an existing valid cached body when available, or returns HTTP 503 with `Retry-After: 5` and `Cache-Control: no-store`.

Generation checks a cooperative 20-second deadline between queries, candidate checks, and rendered entries. Lost ownership, stalled pagination, or an exceeded deadline fails without caching a partial body or replacing an existing static publication. A blocked database or cache driver cannot be interrupted at these checkpoints; its connection and read timeouts still matter. The full corpus has no candidate-count cap.
