📄 content-pipeline-v2-backend-briefing.md 6,079 bytes Apr 22, 2026 📋 Raw

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:

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

# 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

-- 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