feat(publish): strip pipeline scaffolding from body before WP publish#5
Merged
Conversation
- agent_base.py: BaseAgent with use() (tool dispatch) and think() (sole LLM entry point). Skill files drive system prompts. Lazy LLM init. - tools/__init__.py: @register decorator + call() for named tool dispatch. Auto-imports seo and content modules on first load. - tools/seo.py: 6 pure-Python SEO tools (title, meta, keywords, headings, code_blocks, full). seo.full returns score 0-100. - tools/content.py: 6 pure-Python content tools (word_count, headings, code_blocks, hook, paragraphs, structure_summary). - skills/draft.md: WriterAgent system prompt v1.0 (narrative arc only). - skills/critic.md: CriticAgent system prompt v1.0 (4-dimension scoring). - skills/boost.md: BlogBoostAgent system prompt v1.0. - TODOS.md: added PIPE-1 (pipeline mode flag) and SEO-1 (consolidate boost_eval.py) as deferred work items. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add _StructurerSchema (BaseModel) to structurer_agent.py + max_output_tokens=8192 - Add _SEOSchema (BaseModel) to seo_agent.py + max_output_tokens=8192 - Add _WriterSchema (BaseModel) to writer_agent.py (prev fix) + max_output_tokens=8192 - Add _CriticSchema (BaseModel) to critic_agent.py (prev fix) + max_output_tokens=2048 - Add BREWPRESS_MODEL env override to agent_base.py Gemini returns unescaped control chars in markdown strings without structured output. response_schema forces proper JSON escaping for all agents. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Writer → Structurer → SEO → Critic with automatic revision loop (max 3 attempts). Orchestrator now accepts PipelineAgents injection. SEOAgent fast-paths score>=85 on first pass. skills/seo.md and skills/structurer.md added. revision_attempt field added to BlogJob. CriticAgent refactored to extend BaseAgent. tenacity retry added to BaseAgent for 429/5xx. Tests updated for new injection pattern and structured output schemas. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Agent 71 new tests covering skill loading, tool dispatch, LLM lazy init, fast paths, revision loop semantics, and JSON extraction edge cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
draft_agent.py and test_draft_agent.py (918 lines total) are the old single-agent implementation. WriterAgent is the direct replacement. No remaining imports. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 8 new tests for BaseAgent tenacity retry: 429/503 retryable, 400 not, succeeds after 2 failures, reraises after 3 consecutive failures - 2 new CLI tests: pipeline_summary printed when non-empty, not printed when empty Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…idated CLI-1 (auto-approve wiring) and CLI-3 (pipeline_summary output) are fixed by the 4-agent pipeline stack. PIPE-1 (legacy DraftAgent fallback) is invalidated because DraftAgent was deleted. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
response_schema= forces clean JSON from Gemini — no fence stripping needed. Removes ~80 lines of dead code across writer, structurer, seo, and critic agents. Removes 8 obsolete _extract_json tests from the test suite. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eterministic critic scores GAP-2: Add tags, categories, is_single_topic, quality_score, quality_gaps to _WriterSchema. These fields are read in _parse() but were missing from the Gemini structured output schema — causing WP posts to silently get no tags or categories. GAP-3: Add seo_score to BlogJob. SEOAgent stamps it on every returned job (fast path and LLM path). CriticAgent maps it to seo_quality 1–5 via _seo_score_to_quality(), overriding the LLM-derived value deterministically. GAP-4: CriticAgent computes publish_readiness from draft_body_md signals (word count, headings, code blocks, CTA) via _compute_publish_readiness(). Always overrides LLM-derived value. Eliminates 2 dimensions of LLM hallucination in scoring. 631 tests passing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Both are M-effort items that eliminate 0-1 LLM calls per pipeline run each. Deferred post-GA — structure/SEO issues are rule-based and safe to tackle after the 4-agent pipeline proves stable in production. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
RFC-style design covering: - Complete pipeline architecture (6 agents + engagement layer) - EngagementAgent composition (structural checker, fixer, technical checker, gate) - Deterministic quality checks with semantic validation - BlogJob schema with versioning, execution tracking, learning metadata - Error handling: retry logic, 'unknown' state routing, fallback strategies - Cost optimization gates (skip conditions, token limits) - Logging & observability (component-level, metrics segmentation) - Learning layer with knowledge base + post-publish feedback loop - Security: sanitization, idempotency, WordPress deduplication - Complete example walkthrough using Git Worktree blog - Deployment considerations and success criteria Example use case: Git Worktree blog (reference only; system is domain-agnostic) Status: Ready for implementation planning
13 tasks across 4 phases: Phase 1 (Foundation): - Task 1: Extend BlogJob schema with engagement metadata - Task 2: StructuralChecker tool (semantic validation) - Task 3: EngagementFixer tool (auto-improvement) - Task 4: TechnicalChecker tool (code validation) - Task 5: PublishGate tool (decision engine) Phase 2 (Integration): - Task 6: EngagementAgent (composed agent) - Task 7: Sanitizer tool (security gate) - Task 8: Wire into Orchestrator Phase 3 (Resilience): - Task 9: Retry logic with exponential backoff - Task 10: Observability (logging + metrics) Phase 4 (Learning): - Task 11: Knowledge base implementation - Task 12: End-to-end test (Git Worktree example) - Task 13: Documentation Each task is TDD (failing test → implementation → passing test → commit). Includes exact file paths, code snippets, bash commands, expected outputs. Complete and ready for execution.
Add EngagementScoreData, VersioningInfo, ExecutionData, LearningData, PublishingData, PostPublishMetrics, OverrideData models. Extend BlogJob with engagement_data, versioning, execution, learning, publishing, post_publish, override fields. All models use Pydantic with sensible defaults: - EngagementScoreData: tracks structural/technical scores and publish decision - VersioningInfo: captures model version and timestamps - ExecutionData: tracks retries, failures, duration - LearningData: stores content metadata (hook style, CTA type, complexity) - PublishingData: WordPress state (post ID, slug, status) - PostPublishMetrics: engagement metrics (CTR, reads, shares) - OverrideData: audit trail for manual approvals Tests verify schema composition and default values.
Add 7 engagement-related Pydantic models (VersioningInfo, ExecutionData, LearningData, EngagementScoreData, PublishingData, PostPublishMetrics, OverrideData) and PublishDecision enum in engagement_models.py. Extend BlogJob with 7 new fields for tracking versioning, execution, learning, engagement scores, publishing, post-publish metrics, and overrides. All 3 engagement model tests pass. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Add frozen=True to all 7 engagement models via ConfigDict - Create 3 Enum classes: HookStyle, CTAType, CodeComplexity - Convert LearningData string fields to use enums - Add Field(ge=0, le=100) validation to structural_score, technical_score, final_score - Expand test coverage: frozen immutability, score bounds, enum values, edge cases - Export new enums from models/__init__.py - All 8 tests pass; frozen and validation working as expected Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
New module sanitize_body_for_publish() removes three H2 sections that are pipeline metadata, never reader content: - Executed Tutorial Steps (JSON command manifest) - Execution Proof (exit-code block) - Screenshot Plan for the Blog Pipeline H1/H2-aware boundary detection (won't overshoot across an H1 between the stripped H2 and the next H2). Idempotent. Case-insensitive title match. Only H2-level scaffolding titles are stripped; matching H1 left intact. Triggered by post 796 (git-worktree-ai-agents) shipping with raw JSON manifest + exec-proof block visible to readers. Scope: sanitizer module + 12 unit tests + plan doc only. Deferred to follow-up PRs (entangled with sandbox + engagement WIP): - Orchestrator hookup (call sanitizer before publish) - Hero-image picker preferring output_*.png over terminal_*.png - Sandbox tutorial skip-empty-output rule See docs/superpowers/plans/2026-05-04-publish-pipeline-clean-output.md Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sanitize_body_for_publish()— strips three H2 sections that are pipeline metadata, never reader content: Executed Tutorial Steps (JSON command manifest), Execution Proof (exit-code block), Screenshot Plan for the Blog PipelineWhy
Post 796 (`git-worktree-ai-agents`) shipped to WP with raw JSON manifest + exec-proof block visible to readers. Operational hand-fix unblocked that post. This PR adds the durable pipeline guard.
Scope
This PR is intentionally narrow: sanitizer module + tests + plan doc. Deferred to follow-ups (entangled with sandbox + engagement WIP on this worktree):
See `docs/superpowers/plans/2026-05-04-publish-pipeline-clean-output.md` for the full plan.
Test plan
🤖 Generated with Claude Code