diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index f2f8951..b04ec15 100755 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -521,7 +521,10 @@ The posts widget uses WordPress-bundled React (`wp.element`) with raw `createEle The widget fetches posts asynchronously from a dedicated REST endpoint rather than rendering server-side. This keeps initial page load fast and allows the endpoint to be cached independently (5-minute Cache-Control). The permission callback uses a filter (`prautoblogger_rest_posts_public`) so sites can restrict access if needed. ### #13: Run-ID based log linking -Each pipeline execution generates a UUID (`run_id`) that tags every `prab_generation_log` entry. When a post is published, `link_generation_logs()` uses `UPDATE WHERE run_id = X` to associate entries with the `post_id`. This is more reliable than the previous timestamp-window approach, especially in batch runs where multiple posts are generated in quick succession. +Each pipeline execution generates a UUID (`run_id`) that tags every `prab_generation_log` entry. When a post is published, `link_generation_logs()` uses `UPDATE WHERE run_id = X` to associate entries with the `post_id`. This is more reliable than the previous timestamp-window approach, especially in batch runs where multiple posts are generated in quick succession. **v0.8.1+**: `run_id` is also persisted on each post as `_prautoblogger_run_id` post_meta, giving the orphan-research reaper a direct path from run to siblings without walking the gen_log table (see #19). + +### #19: Daily orphan-research-row reaper (v0.8.1) +When a pipeline dies between post creation and the final `Post_Assembler::amortize_research_costs()` call (Hostinger exec kill, OOM, LiteSpeed cut, fatal), the shared `llm_research` cost row stays in `prab_generation_log` with `post_id = NULL` and sibling articles understate their true cost in the breakdown popover. A new daily WP-Cron event `prautoblogger_reap_orphan_research_rows` (hooked to `PRAutoBlogger_Research_Reaper::on_cron`, 03:15 server time — 15 min after the primary generation cron) scans for orphan rows older than a 1-hour grace window, looks up sibling posts by `_prautoblogger_run_id` post_meta (fallback: distinct `post_id`s in gen_log for the same run_id), and delegates to the existing idempotent `amortize_research_costs()` on match. Orphans that still have no siblings after 7 days are deleted outright as sunk cost. A one-time activator migration (`prautoblogger_migrated_run_id_meta_v081`) back-populates `_prautoblogger_run_id` on existing posts from gen_log so the meta-primary path works on upgrade. Manual ops trigger: `wp prautoblogger reap-research`. ### #14: Reddit RSS replaces PullPush.io (and earlier Reddit OAuth) Reddit rejected our OAuth API application (April 2026). We initially switched to PullPush.io, but its index was frequently stale or unavailable. Reddit's RSS/Atom feeds (`/r/{sub}/hot.rss`) proved the most reliable option — they work from datacenter IPs where .json gets 403, require no auth, and have no apparent rate limit. The .json endpoints are kept as a fallback for posts and as the sole source for comment data. Each collected item's metadata includes a `data_source` field (`reddit_rss` or `reddit_json`) for auditability. diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ac782e..a6f95bb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,27 @@ All notable changes to PRAutoBlogger will be documented in this file. Format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project uses [Semantic Versioning](https://semver.org/). +## [0.8.1] — 2026-04-21 + +### Fixed + +- **Orphaned LLM research costs now reaped daily.** When a pipeline died + between post creation and the final cost-amortization step (e.g. + execution-time kill on shared hosting), the `llm_research` row stayed + unlinked and the affected articles' cost popovers understated true spend. + A new daily cron (`prautoblogger_reap_orphan_research_rows`, 03:15 + server time) retroactively amortizes orphan rows against posts from + the same run. Includes a one-time activator migration to back-populate + `_prautoblogger_run_id` post_meta for existing posts. + +### Added + +- New WP-CLI command `wp prautoblogger reap-research` for manual reaping + and ops debugging. +- `Publisher::build_meta()` now writes `_prautoblogger_run_id` on every + generated post, so the reaper has a direct meta path from run_id to + sibling posts without walking `wp_prautoblogger_generation_log`. + ## [0.8.0] — 2026-04-21 ### Changed diff --git a/prautoblogger.php b/prautoblogger.php index 6a5222a..7293201 100644 --- a/prautoblogger.php +++ b/prautoblogger.php @@ -8,7 +8,7 @@ declare(strict_types=1); * Plugin Name: PRAutoBlogger * Plugin URI: https://peptiderepo.com/prautoblogger * Description: Monitors social media for trending topics, generates SEO-friendly blog posts using AI, and publishes them on a daily schedule with full cost tracking and self-improvement metrics. - * Version: 0.8.0 + * Version: 0.8.1 * Requires at least: 6.0 * Requires PHP: 7.4 * Author: PeptideRepo @@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) { | and limits without magic strings. */ -define( 'PRAUTOBLOGGER_VERSION', '0.8.0' ); +define( 'PRAUTOBLOGGER_VERSION', '0.8.1' ); define( 'PRAUTOBLOGGER_DB_VERSION', '1.1.0' ); define( 'PRAUTOBLOGGER_PLUGIN_FILE', __FILE__ ); define( 'PRAUTOBLOGGER_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );