# Blog Content Pipeline — Backend Changes Required **Briefing for Socrates 🧠** **Date:** 2026-04-22 **From:** Wadsworth 📋 **Status:** Content pipeline v1 working, v2 improvements required **Priority:** High — Editorial quality blocker --- ## Problem Statement Current content generation produces **technically correct but editorially hollow** output. **Symptoms:** - Generic "best practice" tutorials - Missing personal stakes or struggle narrative - Polished conclusions without the debugging journey - Sounds like documentation, not lived experience **Root cause:** Prompt structure and validation insufficient for "HoffDesk voice." --- ## Required Changes ### 1. New Prompt Template (v2) **Current:** Generate article about [topic] in [tone] **Required v2:** ``` Write a first-person narrative about [specific incident]. Required elements: - Opening hook: timestamp + location + who was affected - The struggle: at least 2 failed attempts before solution - The moment: when realization hit or system broke - The fix: what worked, with explicit caveats - Reflection: "I learned" or "I'd do differently" Voice rules: - First person only ("I", "my", "we") — never "you should" - One quote from real person or internal monologue - Include "I thought... but..." pattern - Admit one thing you got wrong - Mention the cost: time, sleep, or relationship friction Forbidden: - Generic setup instructions - "Best practices" without personal context - Tutorial-first structure ``` ### 2. Example Injection **Feed as style reference:** - "The Night I Broke DNS and My Wife Couldn't Reach Facebook" - Extract: personal stakes, specific time, emotional beats, struggle narrative **Store in:** `shared/project-docs/blog/style-examples/` - `dns-night.json` — structured breakdown of successful post - Use for few-shot prompting ### 3. Validation Layer **Pre-output checks:** ```python def validate_content(output): checks = { "has_i_statement": r"^I\s+" in first_3_paragraphs, "has_timestamp": r"\d{1,2}:\d{2}" in content, "has_location": extract_location_keywords(), "has_struggle_pattern": r"I thought.*but" in content, "has_cost_mention": r"(hour|minute|sleep|wife|kid)" in content, "no_tutorial_first": not r"^Step 1" in content } return all(checks.values()), failed_checks ``` **On failure:** Return to brief refinement, not auto-regenerate ### 4. Brief Approval Gate **New workflow:** 1. User creates content brief (struggle-first template) 2. Brief validation (automated) 3. **Human approval** — Matt reviews brief before generation 4. Generation with v2 prompt 5. Post-generation validation 6. Output delivery **Why:** Prevents wasting GPU cycles on bad briefs ### 5. New API Endpoint ```yaml # POST /api/v1/content/generate-v2 { "brief": { ... }, # validated struggle-first brief "style_reference": "dns-night", # few-shot example "model": "phi4:14b", # local on Gaming PC "validation_level": "strict" # new checks enabled } # Response: { "content": "...", "validation_passed": true, "checks": { ... }, "estimated_struggle_score": 0.87 # new metric } ``` --- ## Data Model Changes ### New Fields | Field | Type | Purpose | |-------|------|---------| | `struggle_angle` | text | Required narrative hook | | `origin_story` | text | What actually happened | | `attempts` | array | Failed attempts before solution | | `voice_checklist` | object | Boolean validations | | `style_reference` | string | Few-shot example to emulate | | `human_approved` | boolean | Brief approval gate | | `struggle_score` | float | Post-generation quality metric | ### New Tables ```sql -- content_briefs_v2 id, title, struggle_angle, origin_story, attempts[], voice_checklist, human_approved, created_at, approved_at -- style_examples id, slug, title, content_excerpt, structure_analysis, embedding_vector # for semantic similarity matching ``` --- ## Sovereign Constraint Compliance All changes must: - Default to local `phi4:14b` on Gaming PC - Support cloud fallback only for overflow - Use `http://matt-pc.tail864e81.ts.net:11434/v1` - Document local-first architecture in specs --- ## Deliverables | Item | Location | Priority | |------|----------|----------| | Prompt template v2 | `prompts/content_v2.txt` | P0 | | Validation layer | `validation/content_checks.py` | P0 | | Brief approval gate | `api/v1/content/approve-brief` | P0 | | Style example parser | `parsers/style_reference.py` | P1 | | Struggle score calculator | `metrics/struggle_score.py` | P2 | | Updated OpenAPI spec | `shared/api-specs/blog-content-v2.yaml` | P1 | --- ## Testing Strategy ### Unit Tests - Validation layer: pass/fail for known good/bad content - Prompt template: correct injection of examples - Struggle score: correlation with human ratings ### Integration Tests - End-to-end: brief → approval → generation → validation - Fallback: local model failure → cloud retry ### Human Evaluation - Matt rates 10 outputs: old prompt vs new prompt - Target: 80%+ preference for v2 --- ## Dependencies | Dependency | Status | Notes | |------------|--------|-------| | Gaming PC Online | ✅ | phi4:14b ready | | Style examples | 🔄 | Need to extract from "DNS Night" | | Human approval UI | 🔄 | Blocked on Daedalus | | Updated brief form | 🔄 | Blocked on Daedalus | --- ## Open Questions 1. **Struggle score metric:** How to calculate? LLM judge vs heuristic? 2. **Brief approval:** Sync (wait for Matt) or async (queue)? 3. **Style examples:** How many? Auto-extract from published posts? 4. **Fallback:** If local model fails validation, retry or escalate? --- ## Next Steps 1. Review this briefing 2. Estimate effort for prompt + validation layer 3. Draft `prompts/content_v2.txt` 4. Coordinate with Daedalus on brief approval UI 5. Begin implementation when dependencies ready --- **Questions?** File in `shared/project-docs/blog/content-pipeline-v2-backend-questions.md` **Status:** Awaiting Socrates response and effort estimate