feat(phase2b): P2b.3 — SEO stage (_prab_ meta + citation_score) (#180, v0.30.0)

Additive: seo stage writes _prab_* meta per the ratified prcore JSON-LD contract (emitter consumes); computes citation_score + configurable threshold (gate is P2b.4). Deterministic, no LLM/cost, live path untouched. Uninstall purges _prab_ meta. QA APPROVE 55b94d0; CI green (VPS-verified).

Agent-Session: prab-phase2b-3-merge
This commit is contained in:
peptiderepo
2026-06-24 09:24:14 +07:00
committed by GitHub
parent 673866d0cd
commit cf276d353e
10 changed files with 614 additions and 4 deletions

View File

@@ -228,6 +228,7 @@ prautoblogger/
│ │ ├── class-research-source-writer.php # P2b.1: run_sources DB writer for the curate stage; extracted from judge to satisfy 300-line rule (v0.28.0)
│ │ ├── class-editorial-loop.php # P2b.2: bounded editorial loop — editor↔writer ≤editorial_max_rounds — Authority only (v0.29.0)
│ │ ├── class-editorial-revision-caller.php # P2b.2: writer revision LLM step (extracted from editorial-loop for 300-line rule) (v0.29.0)
│ │ ├── class-seo-stage.php # P2b.3: SEO stage — writes _prab_* post-meta (JSON-LD contract) + computes citation_score — Authority only (v0.30.0)
│ │ ├── class-audit-writer.php # run_sources / run_decisions insert layer
│ │ ├── class-pipeline-status.php # Status-transient + summary helpers (extracted from runner/worker)
│ │ ├── class-logger.php # Structured logging singleton (error/warning/info/debug)
@@ -248,6 +249,7 @@ prautoblogger/
│ │ ├── interface-research-fanout.php # P2b.1: contract for parallel research fan-out (v0.28.0)
│ │ ├── interface-research-judge.php # P2b.1: contract for the curate stage judge (v0.28.0)
│ │ ├── interface-editorial-loop.php # P2b.2: contract for bounded editorial loop (v0.29.0)
│ │ ├── interface-seo-stage.php # P2b.3: contract for the SEO stage (v0.30.0)
│ │ ├── class-reddit-provider.php # Reddit data collection orchestrator (RSS primary)
│ │ ├── interface-image-provider.php # Contract for any image generation provider (incl. batch)
│ │ ├── class-open-router-image-provider.php # OpenRouter image gen (single + batch dispatch)
@@ -693,6 +695,7 @@ All prefixed with `prautoblogger_`:
| `prautoblogger_board_poll_interval` | Mission Brief board poll interval in seconds (default 5, min 3). Localized into board.js. |
| `prautoblogger_board_published_window_days` | Days back to show in the Published column (default 7). |
| `prautoblogger_editorial_max_rounds` | Authority-tier editorial loop: max editor↔writer rounds before Review Queue escalation (int, default 3, range 1–10). P2b.2 (v0.29.0). |
| `prautoblogger_citation_score_threshold` | Authority-tier SEO stage: minimum citation_score to pass the publish gate (float, default 0.0 — intentionally uncalibrated; calibrate after first ~10 Authority runs). P2b.3 (v0.30.0). |
### Post Meta
@@ -714,6 +717,12 @@ Stored on every PRAutoBlogger-generated post:
| `_prautoblogger_idea_hash` | v0.18.0 — stable hash of the idea (title|topic); with `_prautoblogger_run_id` forms the post-creation idempotency key |
| `_prautoblogger_og_image_id` | Attachment ID of the composed 1200×630 OG variant (v0.17.0; the rebuilt SEO stage emits `og:image` from this — key name frozen) |
| `_prautoblogger_square_image_id` | Attachment ID of the composed 1080×1080 square variant (v0.17.0; stored now, no consumer yet) |
| `_prab_schema_version` | Int `1` — opt-in trigger for prcore JSON-LD emission (P2b.3 v0.30.0). Presence causes prcore to emit Drug/MedicalWebPage schema. |
| `_prab_citations` | JSON array of kept research sources: `[{url, title, doi?, quality_score?}]` (P2b.3 v0.30.0). |
| `_prab_about_peptides` | JSON array of related peptide post IDs (P2b.3 v0.30.0). |
| `_prab_review_mode` | `editorial-system` (automated SEO stage) or `human` (set in P2b.4 on Review Queue approval). |
| `_prab_reviewed_at` | ISO 8601 datetime of when the SEO stage ran (P2b.3 v0.30.0). |
| `_prab_citation_score` | Float (stored as string): average quality_score of kept sources. Publish gate in P2b.4. |
Composed-variant **attachment** meta (v0.17.0): every pipeline attachment gets
`_prautoblogger_image_role` (`featured`/`og`/`square`); OG/square variants also