diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ff404..f352d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ 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.32.1] - 2026-06-24 + +### Fixed +- P2-A (IA): entry now reflects the 3 P2b.5 steps (curate, seo, authority). Key Options table updated with 7 new Authority option keys: , , , , , , . +- P2-B (virtual field): in now skips any field whose option key ends in before calling . This prevents (the virtual textarea) from being persisted as a raw string; only the parsed array (written by ) is stored. +- P2-C (stub test): upgraded from a tautological string-is-string assertion to real assertions against : all 6 v2 Authority stages (, , , , , ) must be , return non-empty labels, and have distinct labels. + ## [0.32.0] - 2026-06-24 ### Added - P2b.5: Authority pipeline admin controls in Pipeline Settings — master toggle (`prautoblogger_authority_pipeline_enabled`), citation score gate (`prautoblogger_citation_score_threshold`), per-category tier map editor (`prautoblogger_category_tiers_input`/`prautoblogger_category_tiers`) diff --git a/INFORMATION-ARCHITECTURE.md b/INFORMATION-ARCHITECTURE.md index 3288c73..50c1725 100644 --- a/INFORMATION-ARCHITECTURE.md +++ b/INFORMATION-ARCHITECTURE.md @@ -11,7 +11,7 @@ Maintained per DoD v1.1.0 (same-PR update rule). |------|-------|----------|---------| | `prautoblogger-settings` | `PRAutoBlogger_Admin_Page` | `admin-page.php` | Main settings: API Keys, Schedule & Budget, Publishing, Analytics, Display, Images. AI Models / Content / Sources retired to Pipeline Settings in M2 (v0.24.0). | | `prautoblogger-board` | `PRAutoBlogger_Board_Page` | `board-page.php` | Mission Brief board (M5): vertical run-list + right-rail inspector. Status sections: Generating / In review / Published / Failed. New Article button. Stage dot-rail. Inspector: per-stage I/O, cost receipt, dossier link (v0.21.0, v0.27.0). | -| `prautoblogger-pipeline` | `PRAutoBlogger_Pipeline_Settings_Page` | `pipeline-settings-page.php` | Per-step pipeline config: Global Content Context (niche), step option fields, model picker, system instructions, agent prompts, params (M1 v0.23.0; M2 v0.24.0 adds editable step options, retires AI Models/Content/Sources Settings tabs). M3 v0.25.0 adds Template/Preview toggle (assembled-instructions preview from last-run gen_log), version history accordion, and inline diff panel. Three new AJAX endpoints: `prautoblogger_pipeline_preview`, `prautoblogger_pipeline_history`, `prautoblogger_pipeline_diff` (all `manage_options` + nonce gated). | +| `prautoblogger-pipeline` | `PRAutoBlogger_Pipeline_Settings_Page` | `pipeline-settings-page.php` | Per-step pipeline config: Global Content Context (niche), step option fields, model picker, system instructions, agent prompts, params (M1 v0.23.0; M2 v0.24.0 adds editable step options, retires AI Models/Content/Sources Settings tabs). M3 v0.25.0 adds Template/Preview toggle (assembled-instructions preview from last-run gen_log), version history accordion, and inline diff panel. Three new AJAX endpoints: `prautoblogger_pipeline_preview`, `prautoblogger_pipeline_history`, `prautoblogger_pipeline_diff` (all `manage_options` + nonce gated). P2b.5 v0.32.0 adds three Authority-tier steps to the step rail: **Curate** (research judge model/prompts, Authority only), **SEO** (post-meta model/prompts, Authority only), and **Authority Settings** (master toggle + citation gate + per-category tier map editor). | | `prautoblogger-gen-history` | `PRAutoBlogger_Gen_History_Page` | `gen-history-page.php` | M4: Paginated list of all generation runs — title, date, status, models, cost, duration; Stage I/O toggle for inline per-step input/output drill-down (AJAX). Hidden options.php-parent page. `manage_options` + `prautoblogger_gen_run_io` nonce. | | `prautoblogger-dossier` | `PRAutoBlogger_Dossier_Page` | `dossier-page.php` | Per-article generation log + stage edit/re-run (M3). Preferred per-step I/O surface for runs with a linked post. | | `prautoblogger-ideas` | `PRAutoBlogger_Ideas_Browser` | `ideas-browser.php` | Analysis results browser with per-idea generation | @@ -70,6 +70,13 @@ DB version history: 1.0→1.1 (schema normalisation), 1.1→1.2 (M2 dossier), 1. | `prautoblogger_article_queue` | array | — | Checkpoint queue (run_id + ideas + results) | | `prautoblogger_checkpoint_run_id` | string | — | Current run UUID for Tick 2..N finalize path | | `prautoblogger_db_version` | string | — | Installed schema version (triggers dbDelta on mismatch) | +| `prautoblogger_authority_pipeline_enabled` | toggle | 0 | Master switch: ON routes Authority-tier categories through the 6-stage pipeline; OFF = Economy single-pass for all (default, no behaviour change on upgrade) | +| `prautoblogger_category_tiers` | array | [] | Per-category slug → tier map (`authority`\|`economy`). Parsed from the tier-map textarea editor on save. Empty = all categories default to Authority. | +| `prautoblogger_citation_score_threshold` | float | 0 | Minimum source quality score (0–100) for auto-publish gate. 0 = gate disabled while calibrating. | +| `prautoblogger_research_agent_count` | int | 3 | Number of parallel research fan-out agents (1–5). Authority tier only. | +| `prautoblogger_editorial_max_rounds` | int | 3 | Max rounds in the bounded editorial loop (1–5). Authority tier only. | +| `prautoblogger_curate_model` | string | — | Model used for the Curate stage (research judge LLM). Authority tier only. | +| `prautoblogger_seo_model` | string | — | Model used for the SEO stage post-meta enrichment. Authority tier only. | --- @@ -82,4 +89,4 @@ DB version history: 1.0→1.1 (schema normalisation), 1.1→1.2 (M2 dossier), 1. --- -*Last updated: v0.24.0 (2026-06-23)* +*Last updated: v0.32.1 (2026-06-24)* diff --git a/includes/admin/class-pipeline-settings-save-handler.php b/includes/admin/class-pipeline-settings-save-handler.php index 4f8ee43..bf20f55 100644 --- a/includes/admin/class-pipeline-settings-save-handler.php +++ b/includes/admin/class-pipeline-settings-save-handler.php @@ -109,7 +109,16 @@ class PRAutoBlogger_Pipeline_Settings_Save_Handler { $fields = PRAutoBlogger_Pipeline_Settings_Option_Fields::get_fields_for_context( $context ); foreach ( $fields as $field ) { - $id = (string) $field['id']; + $id = (string) $field['id']; + + // Virtual display fields are not persisted directly — they are parsed + // into a canonical option by a dedicated handler. Skip them here. + // prautoblogger_category_tiers_input is the textarea that parse_and_save_category_tiers() + // converts to the prautoblogger_category_tiers serialised array. + if ( str_ends_with( $id, '_input' ) ) { + continue; + } + $raw = isset( $_POST[ $id ] ) ? wp_unslash( $_POST[ $id ] ) : ( $field['default'] ?? '' ); // For checkboxes the POST value is an array (or absent = empty array). if ( 'checkboxes' === ( $field['type'] ?? '' ) ) { diff --git a/prautoblogger.php b/prautoblogger.php index a2f5aa5..15c7891 100644 --- a/prautoblogger.php +++ b/prautoblogger.php @@ -9,7 +9,7 @@ * 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.32.0 + * Version: 0.32.1 * Requires at least: 6.0 * Requires PHP: 7.4 * Author: PeptideRepo @@ -35,7 +35,7 @@ if ( ! defined( 'ABSPATH' ) ) { | Defined here so every file in the plugin can reference paths, versions, | and limits without magic strings. */ -define( 'PRAUTOBLOGGER_VERSION', '0.32.0' ); +define( 'PRAUTOBLOGGER_VERSION', '0.32.1' ); define( 'PRAUTOBLOGGER_DB_VERSION', '1.4.0' ); // No schema change in v0.32.0 (P2b.5 admin controls are additive only). define( 'PRAUTOBLOGGER_DEFAULT_RUN_CEILING_USD', 0.50 ); define( 'PRAUTOBLOGGER_DEFAULT_REQUEST_JSON_RETENTION_DAYS', 14 ); diff --git a/tests/unit/Core/AuthorityStageOrderStubTest.php b/tests/unit/Core/AuthorityStageOrderStubTest.php index 7e5c560..d8d593f 100644 --- a/tests/unit/Core/AuthorityStageOrderStubTest.php +++ b/tests/unit/Core/AuthorityStageOrderStubTest.php @@ -1,13 +1,11 @@ assertIsString( $stage, "Stage '{$stage}' is a valid string identifier." ); + $v2_stages = array( 'research', 'curate', 'draft', 'editorial', 'seo', 'publish' ); + + // All 6 must be registered as known (avoids the humanize fallback). + foreach ( $v2_stages as $stage ) { + $this->assertTrue( + \PRAutoBlogger_Stage_Display_Map::is_known( $stage ), + "Stage '$stage' must be known to Stage_Display_Map (not falling through to humanizer)." + ); } + + // Each must have a non-empty label returned by the map. + foreach ( $v2_stages as $stage ) { + $label = \PRAutoBlogger_Stage_Display_Map::label( $stage ); + $this->assertNotSame( '', $label, "Stage '$stage' must produce a non-empty label." ); + } + + // Labels must be distinct (no two stages share the same display label). + $labels = array_map( + static fn( string $s ) => \PRAutoBlogger_Stage_Display_Map::label( $s ), + $v2_stages + ); + $this->assertCount( + count( $v2_stages ), + array_unique( $labels ), + 'Every Authority stage must have a unique display label.' + ); } /**