v0.4.0
Added
- The Link-headers module (Release 3): RFC 8288 HTTP
Linkheaders that advertise every registered artifact on HTML responses — each singular page's Markdown alternate (rel="alternate",type="text/markdown") and the site-wide/llms.txtand/llms-full.txtsingletons (rel="related",type="text/plain"). Headers are emitted on every HTML response throughsend_headersand skipped on admin, REST, feed,robots.txtand 404 responses; the early-router artifact path is deliberately left undecorated.Discovery_Contextgains a nullable post so a provider can answer both the per-page and the site-wide discovery call, and relations are de-duplicated by the full (href,rel,type) triple. - The Content Signals module (Release 4): a site-wide, tri-state
Content-Signaldeclaration spliced into the virtualrobots.txtunderUser-agent: *, using the Content Signals Policy vocabulary (search/ai-input/ai-train). Each signal is grant (yes), reserve (no) or defer (omitted); the zero-config defaults –search=defer,ai-input=grant,ai-train=defer – emit the single lineContent-Signal: ai-input=yes. An all-defer policy emits nothing and the block is suppressed entirely on a non-public site (blog_public = 0); a new "AI usage" settings section carries the three controls with inline warnings on visibility-reducing choices. A developer filter (kntnt_ai_visibility_content_signals) overrides the resolved policy in code. Specified indocs/spec/content-signals.mdand ADR-0012; theCONTEXT.mdglossary gains the term Content signal. - Developer-filter reference:
docs/EXTENSIBILITY.mddocuments the plugin'skntnt_ai_visibility_*filters – the customisation surface for the Markdown alternates,llms.txt/llms-full.txt, the content signals and caching – with worked examples, and the README gains an Extending section that points to it.
Changed
- The GitHub self-update check is now cached behind a filterable TTL (default six hours,
kntnt_ai_visibility_update_check_ttl) and pinned to the expected GitHub host, so the plugin polls less often and ignores a response served from an unexpected host. - Less filesystem work on the cache-hit serve path: the cache-base real path is memoised and a response's
ETagis computed only when it is needed.
Fixed
- Control characters in a post's title, author or term names are now escaped in the Markdown front matter, so a stray control byte cannot break the YAML block.
/llms.txtno longer emits a section header for a content type that has no eligible posts.- Conditional requests honour a comma-separated
If-None-Matchlist and weak ETags, so a matching validator returns304as it should. - The declared WordPress requirement is corrected to 6.7, from an erroneous 7.0, matching the actual minimum.
Security
- The canonical host used in
Linkheaders and advertised URLs is taken from the site configuration rather than the incomingHostheader, so a spoofedHostcannot influence what the plugin advertises. - Single-flight lock files are written to a namespaced, restricted directory, preventing cross-install collisions and tightening the lock-file location.
Full changelog: https://github.com/Kntnt/kntnt-ai-visibility/blob/v0.4.0/CHANGELOG.md