chore(phase2b): cleanup — repo IA, skip _input raw-store, upgrade stub test (#183, v0.32.1)

Closes 3 Phase 2b P2s. QA APPROVE f3549e8; CI green (phpcs+phpunit VPS-verified).

Agent-Session: prab-phase2b-cleanup-merge
This commit is contained in:
peptiderepo
2026-06-24 18:00:04 +07:00
committed by GitHub
parent 6dd23351cb
commit 81aba2ac23
5 changed files with 64 additions and 19 deletions

View File

@@ -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`)

View File

@@ -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)*

View File

@@ -110,6 +110,15 @@ class PRAutoBlogger_Pipeline_Settings_Save_Handler {
foreach ( $fields as $field ) {
$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'] ?? '' ) ) {

View File

@@ -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 );

View File

@@ -1,13 +1,11 @@
<?php
declare(strict_types=1);
/**
* Placeholder: Authority pipeline stage-order coverage.
* Authority pipeline stage vocabulary and admin integration tests.
*
* This test will be expanded in P2b.1–P2b.4 once those branches merge.
* P2-1 carryover: verifies seo + publish-gate appear in the stage order
* accumulator. The full test lives in AuthorityPipelineTest.php which ships
* with the Authority pipeline classes.
* Tests 1–3 were originally stubs shipping before the Authority pipeline classes.
* Since P2b.4 + P2b.5 are now on main, test 1 is upgraded to a real assertion:
* Stage_Display_Map must return non-empty labels for every v2 Authority stage.
* Tests 2–4 exercise live admin classes (step rail + model option allowlist).
*
* @package PRAutoBlogger\Tests\Core
* @group authority
@@ -20,16 +18,40 @@ use PRAutoBlogger\Tests\BaseTestCase;
class AuthorityStageOrderStubTest extends BaseTestCase {
/**
* Canonical stage vocabulary includes all 6 Authority stages + publish.
* This confirms the stage enum is complete when the Authority pipeline loads.
* Stage_Display_Map must return non-empty, distinct labels for the six
* canonical Authority v2 stages: research, curate, draft, editorial, seo, publish.
*
* This replaces the tautological "$stage is a string" stub shipped in P2b.5.
* We verify the map has real entries (not the humanized fallback) for every stage
* so the audit/dossier UI never renders a blank or auto-generated label.
*/
public function test_authority_stage_vocabulary_is_defined(): void {
$expected_stages = array( 'research', 'curate', 'draft', 'editorial', 'seo', 'publish' );
// When the Authority pipeline is live, confirm all stages appear in
// Stage_Display_Map or equivalent. This stub passes until then.
foreach ( $expected_stages as $stage ) {
$this->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.'
);
}
/**