Skip to content

WordPress plugin: serve llms.txt from the site's own pages - #4

Merged
zordhalo merged 2 commits into
mainfrom
feat/wordpress-plugin
Sep 24, 2026
Merged

zordhalo merged 2 commits into
mainfrom
feat/wordpress-plugin

Conversation

@zordhalo

Copy link
Copy Markdown
Contributor

ADV-288. WordPress is the one surface in this plan with a plausible path to four figures, because its plugin directory is a search surface with its own SEO — people find plugins by typing into wp-admin, not by reading our docs.

It serves /llms.txt rather than writing one

Every other generator writes the file to disk once. On WordPress that's wrong twice over: plenty of hosts have a read-only or inconsistently writable web root, and a file written today is stale the moment somebody publishes a page.

This answers a rewrite rule from the posts table, cached in a transient dropped on any publish, edit or delete. Publish a page and the machine reading includes it.

A real file at the web root still wins, because rewrite rules only run when WordPress does. Deliberate: a site already publishing its own keeps it.

It will not invent facts

An empty About produces a TODO, not generated prose. A machine reading that states something the site does not support is worse than none, because a model repeats it. Privacy policy, password-protected content and untitled pages are excluded, so the file only ever contains what is already public.

The guard is enqueued, not documented

human-machine-swapper:not(:defined){display:none} is the one thing a WordPress user cannot reasonably be expected to get right by hand, so the plugin enqueues it. They cannot skip it.

The script tag is version-pinned with an integrity hash via a script_loader_tag filter scoped to our handle, since WordPress has no SRI API. That also forces ver => null — a ?ver= query string would break the hash match.

Verification, in two layers

Linting only proves it parses. So there's a thin stub of the WordPress functions the generator touches, letting the generator actually run:

generator, with everything filled in        8 ok
generator, with nothing filled in           3 ok   (TODO fallback, tagline fallback)
generator, with HTML pasted in              2 ok   (tags stripped, text kept)
generator, page cap                         1 ok
all passing

CI lints at PHP 7.4, the declared floor, not at whatever the runner ships. Syntax that is fine on 8.x and fatal on 7.4 is exactly the failure a user hits and we would not.

Not submitted yet

WordPress.org is a manual review queue and then SVN, not git. wordpress/README.md has the steps. The screenshots readme.txt references still need taking against a real install.

🤖 Generated with Claude Code

WordPress is the one surface in this plan with a plausible path to four figures,
because its plugin directory is a search surface with its own SEO: people find
plugins by typing into wp-admin, not by reading our docs.

It SERVES /llms.txt rather than writing one. Every other generator writes the file
to disk once, which is wrong twice over here: plenty of hosts have a read-only or
inconsistently writable web root, and a file written today is stale the moment
somebody publishes a page. This answers a rewrite rule from the posts table,
cached in a transient that drops on any publish, edit or delete. A real file at
the web root still wins, because rewrite rules only run when WordPress does, so a
site already publishing its own keeps it.

It will not invent facts. An empty About produces a TODO, not generated prose: a
machine reading that states something the site does not support is worse than
none, because a model repeats it. Privacy policy, password-protected content and
untitled pages are all excluded, so the file only ever contains what is already
public.

The :defined guard is enqueued by the plugin rather than documented, which is the
one thing a WordPress user cannot reasonably be expected to get right by hand. The
script tag is version-pinned with an integrity hash, added through a
script_loader_tag filter scoped to our handle, since WordPress has no SRI API.
That also forces ver => null: a ?ver= query string would break the hash match.

Verification is two layers, because linting only proves it parses. A stub of the
fourteen WordPress functions the generator touches lets the generator actually run,
and 14 assertions cover the exclusions, the TODO fallback, tag stripping and the
page cap. CI lints at PHP 7.4, the declared floor, not at whatever the runner
ships: syntax that is fine on 8.x and fatal on 7.4 is exactly the failure a user
hits and we would not.

Not submitted to the directory. That is a manual review queue and then SVN, and
the screenshots readme.txt references still need taking against a real install.
CI failed on the first run with 'Call to undefined function str_starts_with'.
str_contains and str_starts_with are PHP 8.0, and local PHP is 8.5, so the test
passed here while being incapable of running on the version the plugin declares
support for.

The plugin itself was already clean; only the test was not. That is the more
useful half of the result: a suite that cannot run at the floor quietly stops
testing the version users are on, and the only reason this surfaced in minutes is
that CI pins 7.4 rather than taking whatever the runner ships.
@zordhalo
zordhalo merged commit 570d3bd into main Sep 24, 2026
2 checks passed
@zordhalo
zordhalo deleted the feat/wordpress-plugin branch September 24, 2026 06:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant