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
- Struggle score metric: How to calculate? LLM judge vs heuristic?
- Brief approval: Sync (wait for Matt) or async (queue)?
- Style examples: How many? Auto-extract from published posts?
- Fallback: If local model fails validation, retry or escalate?
Next Steps
- Review this briefing
- Estimate effort for prompt + validation layer
- Draft
prompts/content_v2.txt - Coordinate with Daedalus on brief approval UI
- 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