Commit Graph

9 Commits

Author SHA1 Message Date
peptiderepo
6b1908d628 fix(maintenance): v0.18.2 — four confirmed-live fixes
1. Cost-reporter SQL: phpcs:ignore annotations were embedded inside two SQL
   string literals (get_daily_spend, get_spend_by_stage), causing MariaDB to
   reject both queries and break the Metrics & Costs admin page. Moved annotations
   above the prepare() calls. Regression tests added to CostReporterTest.

2. Collector failure observability: catch block in collect_from_all_sources() now
   logs structured meta (model slug, HTTP status parsed from exception message,
   first 200 chars of error body) so outage incidents are diagnosable post-hoc.

3. run_stages.agent_role back-write: Pipeline_Runner, Article_Worker, and
   Content_Generator were calling Run_Stage_State::start() with agent_role=''.
   All start() call sites now pass Stage_Display_Map::default_agent_role(stage).
   Role written at INSERT only; ON DUPLICATE KEY UPDATE does not include
   agent_role — idempotency-key semantics on resume are unchanged.

4. Runware float deprecation: normalize_seed() applied % to a float
   (microtime(true) * 1000), triggering PHP 8 deprecation on every image
   generation. Fixed with (int) round(...) before the modulo operator.

Refs: convo/prautoblogger/threads/2026-06-pipeline-v2-phase1/25-cto-v0182-maintenance.md
Agent-Session: prab-v0182-maintenance-20260612
2026-06-12 09:16:40 +07:00
peptiderepo
50da840553 feat(runs): state machine, idempotent resume, reaper extension, retention
Pipeline v2 Phase 1, commit 4/4. Run_Stage_State persists per-run
per-stage state keyed run_id + stage + agent_role + item_key (item_key
scopes articles because one run_id spans a whole batch; agent_role is
the Phase-2 quorum dimension, schema-only). Done stages snapshot output
and are reused on re-entry — writer stages via
Content_Generator::set_run_item, the review via its stored verdict, a
published item skipped outright — never re-run, never re-charged. Post
creation is keyed by _prautoblogger_run_id + new _prautoblogger_idea_hash
(check-before-insert in Publisher) so retries cannot duplicate posts.
Run-level research/analysis checkpoints + done/failed lifecycle marks
ride Pipeline_Runner/Executor (incl. orphan-abort + budget-abort paths).

Run_Reaper rides the EXISTING #19 daily cron: stages stuck running >2x
expected stage wall-clock and runs silent >2x expected run wall-clock ->
failed (filterable), open stages reaped, queryable as 'incomplete'.
Retention: request_json + stage output payloads NULLed after R days, R
from the new Audit Payload Retention setting (default constant 14,
0 = keep forever, no literal at point of use). Audit_Writer records
editorial verdicts (run_decisions) and per-article kept sources
(run_sources) for new runs.

Under-300: status-transient/summary helpers extracted verbatim to
Pipeline_Status (Pipeline_Runner 271; removed the worker's duplicate).

Agent-Session: pipeline-v2-phase1-engineer-20260612
2026-06-11 16:42:56 +07:00
peptiderepo
b9dfc29436 fix: image style suffix empty-string bypass + image cost run_id mismatch (v0.12.2)
Bug 1: extract get_style_suffix() helper that treats '' as "use default", applied to all 3 call sites in class-image-prompt-builder.php.

Bug 2: thread $cost_tracker through ArticleWorker → Publisher → PostAssembler → ImagePipeline so image costs share the article's run_id in wp_prautoblogger_generation_log.

Version: 0.12.1 → 0.12.2
Reviewed-by: peptiderepo (CTO)
QA: qa-reviews/prautoblogger/2026-04-23-7669a9c1.md
2026-04-24 01:36:46 +07:00
peptiderepo
fbbb387311 feat: Opik LLM observability tracing skeleton (Wave 1) — v0.12.0
Wires PRAutoblogger into Comet Opik cloud for per-call tracing.

- Thin PHP REST client (class-opik-client.php, 276 LOC)
- Async fire-and-forget dispatch via wp_schedule_single_event
- Feature flag PRAUTOBLOGGER_OPIK_ENABLED defaults OFF
- One trace per article, 5 spans across content-generator + chief-editor
- Exponential backoff 2s/4s/8s, max 3 retries, drops on failure
- Admin settings page (api-key configured indicator only, never rendered)
- ARCHITECTURE.md + CONVENTIONS.md updated

PR #113 — QA gate: PASS (qa-reviews/prautoblogger/2026-04-23-0d8dc67.md)
2026-04-23 22:36:24 +07:00
peptiderepo
0e1551be42 fix(phpcs): move ignore pragmas into file-level docblocks
File-level sniffs like WordPress.Files.FileName are evaluated at the file level,
not at code level. They require phpcs:ignore directives to be placed within the
file-level docblock (/** ... */), not in code comments.

Moved all 81 phpcs:ignore pragmas from code comments to the file-level docblocks.
This applies to:
- 79 class files with class-naming convention ignores
- prautoblogger.php with strict-types docblock ignore
- uninstall.php with strict-types docblock ignore
2026-04-23 03:26:50 +00:00
peptiderepo
dc86376e8b style(phpcs): resolve 137 residual WordPress-Core violations
- Added phpcs:ignore for class file naming convention (79 violations)
  WordPress.Files.FileName.InvalidClassFileName is a known architectural
  issue — class files use short names without prautoblogger- prefix

- Added phpcs:ignore for ->prepare() table interpolation (56 violations)
  WordPress.DB.PreparedSQL.InterpolatedNotPrepared: dynamic table names
  (prab_generation_logs, prab_cost_logs) require interpolation; ->prepare()
  does not support table name placeholders, only column values

- Fixed file-level docblock positioning (2 violations)
  prautoblogger.php and uninstall.php: moved declare(strict_types=1) before
  file docblock per PHP best practices
2026-04-23 03:23:52 +00:00
peptiderepo
f3eacd0d8d style(phpcs): autofix WordPress-Core violations via phpcbf
Run phpcbf --standard=WordPress-Core across includes/, prautoblogger.php,
and uninstall.php. Fixed 1,362 formatting violations in 75 files:
  - Short array syntax: [] → array()
  - Line breaking for long function calls
  - Consistent indentation
  - Function call parameter alignment

No logic changes; purely mechanical formatting.
2026-04-23 02:42:48 +00:00
peptiderepo
cc6979b085 Fix false stall detection for multi-article chained generation
The frontend status poller measured elapsed time from `started` (set once
at the beginning of the run) and declared a stall at 300s.  Three articles
take ~6 minutes total, so the poller always false-alarmed on article 3.

Now every stage broadcast writes `last_updated` into the transient, and
the stall check compares idle time since the last update — not since the
run started.  This lets N-article runs complete without false timeout as
long as each individual article finishes within 5 minutes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 03:40:05 +07:00
peptiderepo
ef40ce91d4 feat: chain per-article cron jobs to eliminate execution time ceiling
The pipeline previously ran all articles sequentially in a single PHP
process. On Hostinger, this timed out at ~120s — enough for 1 article
but not 2+. Now the pipeline generates article 1 in-process, then
queues articles 2..N as individual WP-Cron events. Each article gets
its own PHP process with its own execution time budget, so we can
generate any number of articles regardless of server time limits.

Architecture:
- Pipeline_Runner: orchestrate (collect+analyze+score) + first article,
  then serialize remaining ideas to wp_options and chain cron events
- Article_Worker (new): focused single-article worker extracted from
  the pipeline loop — content gen + editorial + publish
- Executor: new on_process_article_queue() handler for chained events;
  status poller re-schedules orphaned queue jobs automatically
- Article_Idea: added to_array() for queue serialization

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 03:26:37 +07:00