Skip to content

Releases: bitcryptic-gw/mdf-analytics-wp

v0.1.9

Choose a tag to compare

@github-actions github-actions released this 01 Sep 09:11

Fixed

  • Backfill recovery when the scheduled mdf_backfill_batch single cron event
    is lost to a race with another scheduler (observed in production with Action
    Scheduler). mdf_start_backfill() now verifies the event persisted after
    scheduling and retries once, and a self-heal check re-schedules the batch
    whenever the queue still has work but no batch event is pending (runs on the
    existing purge cron and on admin page loads — no new cron schedule).
    Previously the backfill could stall indefinitely with a populated queue and
    no scheduled event, requiring a manual Settings-toggle re-trigger.
  • Per-post markdown rebuilds (mdf_markdown_rebuild, queued on save_post
    when edited content changes) get the same protection: scheduling now verifies
    the single event persisted and retries once, records a lightweight per-post
    pending marker, and the self-heal check re-schedules any stale pending
    rebuild whose event was lost to the same cron write race.

Added

  • Persistent markdown-coverage status line on the Settings page, shown whenever
    "Offer markdown to agents" is enabled: while a backfill runs it keeps the
    existing in-progress counter; once complete it shows "N of M published
    posts/pages have a cached markdown version." (live count of cached .md
    files vs. published content eligible for conversion), or "No published
    content yet to convert." on an empty site. Hidden when the toggle is off.

v0.1.6

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 16 Jul 04:07

[0.1.6] - 2026-07-16

Fixed

  • Backfill batch processor (mdf_cron_backfill_batch()) no longer counts a post as
    processed when its conversion/write actually failed — mdf_backfill_processed now
    reflects successful conversions only, not attempts. Previously the counter incremented
    unconditionally regardless of the return value of mdf_convert_post(), which could
    make the admin UI report a completed backfill with zero cache files actually written.
  • Added a writability check for the markdown cache directory (wp-content/uploads/mdf-cache/posts/)
    before attempting any write, in both the batch processor and mdf_convert_post() directly.
    If the directory is not writable by the web server user, the failure is now recorded and
    surfaced as a visible admin notice on the Settings page (mdf_cache_writable_error option),
    instead of failing silently. The notice self-clears once the directory becomes writable again.
  • mdf_create_cache_dirs() now also attempts chmod 0775 on the cache base and posts/
    directories at creation time, as a best-effort mitigation for installs where the directory
    ends up owned by a different user than the one serving requests.

Changed

  • Settings page copy: "posts" replaced with "content" in the markdown-offering toggle
    description and backfill progress status line, since the pipeline covers pages and
    custom post types as well as posts.
  • Settings page "Phase 3 (roadmap)" description updated to "Phase 3 — shipped" since
    the CommonMark auto-generation pipeline is now live. Phase 2 (wallet/earning) remains
    the only future roadmap item.

Known limitation

  • If plugin activation runs as a different user than the web server process (e.g. root during
    a Docker build step, vs. www-data serving real requests), the chmod added above may not
    be sufficient to make the directory writable, since it changes permission mode but not
    ownership. The runtime writability check and admin notice are the actual safety net in that
    case. A cleaner fix (explicit ownership correction, or moving directory creation to first-request
    time under the serving user) may be considered for a future release if this recurs.

v0.1.5

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 12 Jul 13:40

Supersedes v0.1.4, which was cut one commit before the MDF_VERSION constant fix landed. v0.1.4 should not be used. This release includes that fix (header and constant both correctly read 0.1.4 internally — the git tag is 0.1.5 as the release identifier).

v0.1.4

v0.1.4 Pre-release
Pre-release

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 09 Jul 05:33

Added

  • Vendored league/html-to-markdown (v5.1.1) with namespace scoping (MdfAnalytics\Vendor\League\HTMLToMarkdown) to eliminate class-redeclaration collisions if another plugin also vendors the same upstream library. No Composer required at runtime — the library is source-committed. Scoped via humbug/php-scoper, built by build-vendor.sh.
  • Pre-build markdown cache pipeline: all published posts are converted to CommonMark on save (via WP-Cron background job) and served to clients that send Accept: text/markdown. Markdown is never served for a URL until a pre-built .md file actually exists for it — no live-conversion fallback.
  • Cache directory at wp-content/uploads/mdf-cache/ with flat posts/ layout, per-post {post_id}.md + {post_id}.meta.json sidecars, and a manifest.json aggregate.
  • Settings toggle "Offer markdown to agents" — enabling it auto-queues a full backfill of all published posts. Disabling stops markdown serving immediately.
  • save_post hook computes content hash (SHA-256 of the_content() post-filter output) and skips rebuilds when unchanged. Atomic temp-file + rename writes keep the old .md servable throughout a rebuild.
  • template_redirect negotiation gating: checks file_exists() against the cached .md (single filesystem stat, no sidecar JSON read at request time), sets Vary: Accept and Content-Type: text/markdown only when cached content exists.
  • Backfill uses batched WP-Cron (mdf_backfill_batch) to avoid flooding the cron queue; admin notice shows progress during backfill.

Fixed

  • Manifest read-modify-write race: manifest.json updates are now wrapped with flock(LOCK_EX), preventing concurrent WP-Cron-driven writes (e.g. overlapping mdf_markdown_rebuild and mdf_backfill_batch events) from silently clobbering each other. The lock provides advisory exclusion around mdf_manifest_record_result() and the backfill-completion path; the existing atomic temp-file + rename is retained for reader safety.

v0.1.3

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 09 Jul 05:33

Added

  • Plugin now serves a curated llms.txt at the site root (/llms.txt), sourced from the file shipped in the plugin directory. Supports GET/HEAD, Last-Modified/If-Modified-Since conditional requests, and 1-hour public caching. Requests are logged through the existing analytics classifier.

v0.1.2

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 10 Jun 02:08
0ac7c0e

Fixed

  • Type-2 (known agent) UA snippet now stores the matched agent fragment rather than the first token of the raw UA string. Bots that send Mozilla/5.0 (compatible; Googlebot/2.1; ...) style UAs now display as Googlebot in the dashboard rather than the misleading Mozilla prefix. Affects all standard search and AI crawler UAs. Historical rows are unaffected and will age out within the 90-day retention window.

Changed

  • mdf_classify_ua() and mdf_ua_snippet() consolidated into a single mdf_classify_ua_with_snippet() function that performs classification and snippet extraction in one pass, eliminating redundant UA string traversal.

v0.1.1

v0.1.1 Pre-release
Pre-release

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 10 Jun 02:02
2225c75

Fixed

  • WordPress core self-calls (WordPress/), Jetpack, and uptime monitors (UptimeRobot, Pingdom, etc.) now correctly classified as type-3 (internal/monitor) and excluded from agent counts and estimated earnings. Sites running v0.1.0 will have these requests miscategorised as type-1 or type-2 in historical data; rows clear automatically within 90 days, or truncate wp_mdf_requests manually to reset immediately.

v0.1.0

v0.1.0 Pre-release
Pre-release

Choose a tag to compare

@bitcryptic-gw bitcryptic-gw released this 10 Jun 02:01
124ea11

Added

  • Initial release.
  • Passive request logging on WordPress shutdown hook — no content modification, no payment processing.
  • Visitor classification: type-2 known agent (40+ UA fragments covering AI assistants, agentic frameworks, search crawlers, and generic HTTP clients), type-1 likely automated (heuristic — no browser engine markers), type-3 internal/monitor (WordPress platform calls, uptime monitors, CDN health probes), type-0 human (not logged unless Accept: text/markdown present).
  • wants_markdown flag logged per request when Accept: text/markdown is present in the request headers.
  • 90-day retention via daily WP-Cron purge.
  • Admin dashboard with 7/30/90-day window selector, seven stat cards (total requests, known agents, likely automated, internal/monitors, wanted markdown, estimated earned, estimated missed), daily bar chart, top agents table, internal/monitors table, top markdown-requested paths table.
  • Settings page: currency selector (sats / USDC), configurable per-request rate for earnings estimates.
  • Phase 2 callout CTA in dashboard footer.
  • No IP addresses stored. No external HTTP requests. No dependencies beyond WordPress core.