Files
BSN-Chatsystem/spec_article_pipeline_2026-06-23.html
T
2026-06-23 14:26:02 +02:00

383 lines
17 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Anforderungsdefinition: Vollautomatischer Artikel-Workflow</title>
<meta name="description" content="Spezifikation für eine vollautomatische Pipeline von Input (Thema/PDF/URL) → QC-geprüfter HTML-Artikel. Stages: Input Prep → Research → Write → QC → Deliver.">
<style>
:root {
--accent: #20228a;
--accent-light: #3b3da8;
--bg: #f8f9fb;
--surface: #ffffff;
--text: #1a1a2e;
--text-muted: #6b7280;
--border: #e5e7eb;
--radius: 10px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif; background: var(--bg); color: var(--text); line-height: 1.6; padding: 2rem 1.5rem; max-width: 900px; margin: 0 auto; }
header { margin-bottom: 2.5rem; padding-bottom: 1.5rem; border-bottom: 3px solid var(--accent); }
h1 { font-size: 1.8rem; color: var(--accent); margin-bottom: 0.4rem; letter-spacing: -0.02em; }
header p { color: var(--text-muted); font-size: 0.95rem; }
h2 { font-size: 1.3rem; color: var(--accent); margin: 2rem 0 0.8rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--border); }
h3 { font-size: 1.1rem; color: var(--accent-light); margin: 1.5rem 0 0.5rem; }
h4 { font-size: 1rem; color: #444; margin: 1rem 0 0.3rem; }
p, li { margin-bottom: 0.5rem; }
ul, ol { padding-left: 1.5rem; margin-bottom: 1rem; }
li { margin-bottom: 0.25rem; }
code { background: #f0f0f5; padding: 0.15em 0.4em; border-radius: 4px; font-size: 0.9em; font-family: 'SF Mono', 'Fira Code', monospace; }
pre { background: #1a1a2e; color: #e0e0e0; padding: 1rem 1.2rem; border-radius: var(--radius); overflow-x: auto; font-size: 0.85rem; line-height: 1.5; margin: 1rem 0; }
pre code { background: none; padding: 0; color: inherit; }
table { width: 100%; border-collapse: collapse; margin: 1rem 0; background: var(--surface); border-radius: var(--radius); overflow: hidden; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
th { background: linear-gradient(135deg, var(--accent), var(--accent-light)); color: #fff; font-weight: 600; padding: 0.6rem 0.8rem; text-align: left; font-size: 0.9rem; }
td { padding: 0.5rem 0.8rem; border-bottom: 1px solid var(--border); font-size: 0.9rem; }
tr:last-child td { border-bottom: none; }
tbody tr:nth-child(even) { background: rgba(32,34,138,0.03); }
.pipeline { display: flex; align-items: center; gap: 0.3rem; flex-wrap: wrap; font-family: monospace; font-size: 0.85rem; margin: 1rem 0; padding: 0.8rem; background: var(--surface); border-radius: var(--radius); overflow-x: auto; }
.stage { background: linear-gradient(135deg, var(--accent), var(--accent-light)); color: #fff; padding: 0.3rem 0.6rem; border-radius: 6px; white-space: nowrap; font-weight: 600; }
.arrow { color: var(--accent); font-weight: bold; }
.badge { display: inline-block; padding: 0.15em 0.5em; border-radius: 4px; font-size: 0.8rem; font-weight: 600; margin-right: 0.3rem; }
.badge-green { background: #d1fae5; color: #065f46; }
.badge-red { background: #fee2e2; color: #991b1b; }
.badge-blue { background: #dbeafe; color: #1e40af; }
.badge-yellow { background: #fef3c7; color: #92400e; }
.checklist { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; margin: 1rem 0; }
.checklist-item { display: flex; align-items: flex-start; gap: 0.4rem; padding: 0.3rem 0; font-size: 0.9rem; }
.checklist-item .icon { flex-shrink: 0; width: 1.3em; }
hr { border: none; border-top: 1px solid var(--border); margin: 2rem 0; }
footer { margin-top: 3rem; padding-top: 1rem; border-top: 1px solid var(--border); color: var(--text-muted); font-size: 0.85rem; }
</style>
</head>
<body>
<article>
<header>
<h1>Anforderungsdefinition: Vollautomatischer Artikel-Workflow</h1>
<p>Spezifikation für Cody · 23. Juni 2026 · Stand: final</p>
</header>
<h2>1. Ziel</h2>
<p>Eine Pipeline, die aus einem beliebigen Input (Thema, PDF, URL, Stichwort) einen <strong>QC-geprüften, publikationsfertigen HTML-Artikel</strong> produziert. Basti gibt den Auftrag — der Rest läuft autonom.</p>
<h2>2. Eingabe-Schnittstelle</h2>
<pre><code>Input: {
topic: string, // "Gamegenic wird Partner von Tolarian Community College"
sources: string[], // ["/pfad/pm.pdf", "https://icv2.com/...", "https://gamegenic.com"]
category_id: number, // Joomla-Rubrik (default: 61 = Korrektur)
rubric: string, // "Neuerscheinungen" | "Crowdfunding" | "Nachrichten" | ...
image_urls: string[], // optionale Bild-URLs aus PM
deadline: string | null // optional: ISO-Timestamp für zeitkritische Artikel
}</code></pre>
<h3>Input-Quellen-Erkennung (automatisch)</h3>
<table>
<tr><th>Input</th><th>Quelle</th></tr>
<tr><td>PDF</td><td>Pfad aus <code>~/.hermes/cache/documents/</code></td></tr>
<tr><td>URL</td><td>Direkt übernehmen</td></tr>
<tr><td>Nur Thema</td><td>Sub-Agent recherchiert selbstständig Quellen</td></tr>
</table>
<h2>3. Pipeline-Stufen</h2>
<div class="pipeline">
<span class="stage">STAGE 0<br>Input Prep</span>
<span class="arrow"></span>
<span class="stage">STAGE 1<br>Research</span>
<span class="arrow"></span>
<span class="stage">STAGE 2<br>Write</span>
<span class="arrow"></span>
<span class="stage">STAGE 3<br>QC</span>
<span class="arrow"></span>
<span class="stage">STAGE 4<br>Deliver</span>
</div>
<p style="font-size:0.85rem;color:var(--text-muted);margin-top:0.3rem;">Dauer: ~1015 Minuten von Input bis fertigem Artikel</p>
<h3>STAGE 0: Input Preparation</h3>
<p><span class="badge badge-blue">Basti</span> (nicht Sub-Agent)</p>
<ol>
<li>PDFs OCRen: <code>python3 -c "import pymupdf; doc=pymupdf.open('…'); [print(page.get_text()) …]"</code></li>
<li>Prompt bauen aus Input + OCR-Text + Quellen-URLs</li>
<li>Skills-Array: <code>["journalistic-article-writing", "korrekturschleife", "article-management"]</code></li>
<li>Toolsets: <code>["web", "terminal", "file", "search", "skills"]</code></li>
</ol>
<p><strong>Output:</strong> Fertiger Prompt für Stage 1</p>
<h3>STAGE 1: Research</h3>
<p><span class="badge badge-green">Sub-Agent #1</span> (Leaf, <code>delegate_task</code>)</p>
<table>
<tr><th>Feld</th><th>Wert</th></tr>
<tr><td>Skills</td><td>journalistic-article-writing</td></tr>
<tr><td>Toolsets</td><td>web, terminal, file, search, skills</td></tr>
</table>
<ol>
<li>Alle Quellen abrufen (<code>web_extract</code>, <code>curl</code>, <code>web_search</code>)</li>
<li>Jede Quelle bewerten: <strong>AAA</strong> (Primär) / <strong>AA</strong> (Sekundär) / <strong>A</strong> (schwach)</li>
<li>Fehlende Fakten ergänzen:
<ul>
<li>BGG-Eintrag suchen: <code>web_search site:boardgamegeek.com SPIELNAME</code></li>
<li>Autor/Illustrator/Verlag verifizieren</li>
<li>Preise, Daten, Awards gegenprüfen</li>
</ul>
</li>
</ol>
<p><strong>Output:</strong> <code>research_brief.md</code></p>
<pre><code># Research Brief: THEMA
## Quellenbewertung
| Quelle | Stufe | URL |
|---------|---------|-----------------------|
| PM | AAA | https://gamegenic.com |
## Fakten
- Fakt 1 (Quelle: URL, AAA)
- Fakt 2 (Quelle: URL, AA)
## Offene Punkte
- Punkt X konnte nicht verifiziert werden → STREICHEN</code></pre>
<p><strong>Exit-Codes:</strong> <span class="badge badge-green">0</span> = vollständig · <span class="badge badge-red">1</span> = unvollständig (Abbruch, an Basti melden)</p>
<h3>STAGE 2: Write</h3>
<p><span class="badge badge-green">Sub-Agent #2</span> (Leaf, <code>delegate_task</code>)</p>
<table>
<tr><th>Feld</th><th>Wert</th></tr>
<tr><td>Skills</td><td>journalistic-article-writing, korrekturschleife, article-management</td></tr>
<tr><td>Toolsets</td><td>web, terminal, file, search, skills</td></tr>
<tr><td>Context</td><td>Research Brief + Original-Prompt</td></tr>
</table>
<div class="checklist">
<div class="checklist-item"><span class="icon"></span> KEINE "XML API v2" → klickbare BGG-Links</div>
<div class="checklist-item"><span class="icon"></span> KEIN "Betriebsgeheimnis"</div>
<div class="checklist-item"><span class="icon"></span> Quellen = <code>&lt;a href="…" target="_blank"&gt;</code></div>
<div class="checklist-item"><span class="icon"></span> <code>&lt;span&gt;&lt;strong&gt;Quellen&lt;/strong&gt;&lt;/span&gt;</code></div>
<div class="checklist-item"><span class="icon"></span> KEINE Emojis/Icons</div>
<div class="checklist-item"><span class="icon"></span> Datei endet mit <code>&lt;/html&gt;</code></div>
</div>
<p><strong>Output:</strong> <code>/home/hermes/workspace/artikel_NAME_DATUM.html</code></p>
<p><strong>Pflicht-Elemente im HTML:</strong></p>
<pre><code>&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;TITEL&lt;/title&gt;
&lt;meta name="description" content="…"&gt;
&lt;meta name="keywords" content="…"&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;article&gt;
&lt;h1&gt;TITEL&lt;/h1&gt;
&lt;p class="meta"&gt;DATUM · Lesezeit: ca. N Minuten&lt;/p&gt;
&lt;!-- Inhalt --&gt;
&lt;hr id="system-readmore" /&gt;
&lt;span style="…"&gt;&lt;strong&gt;Quellen&lt;/strong&gt;&lt;/span&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="URL" target="_blank"&gt;Name&lt;/a&gt; — Beschreibung&lt;/li&gt;
&lt;/ol&gt;
&lt;p class="qc"&gt;&lt;!-- QC: Quelle1=AAA|URL, … --&gt;&lt;/p&gt;
&lt;/article&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
<p><strong>Exit-Codes:</strong> <span class="badge badge-green">0</span> = Artikel geschrieben · <span class="badge badge-red">1</span> = Fehler</p>
<h3>STAGE 3: Quality Control</h3>
<p><span class="badge badge-green">Sub-Agent #2</span> (gleicher Agent, nach dem Schreiben)</p>
<pre><code>bash /home/hermes/workspace/verify_article.sh artikel_NAME.html</code></pre>
<h4>13 Checks (Stand 23.06.2026)</h4>
<table>
<thead>
<tr><th>#</th><th>Check</th><th>Kriterium</th></tr>
</thead>
<tbody>
<tr><td>1</td><td>Read-More</td><td>Genau 1 × <code>&lt;hr id="system-readmore"&gt;</code></td></tr>
<tr><td>2</td><td>br nach Read-More</td><td>Kein <code>&lt;br&gt;</code> direkt danach</td></tr>
<tr><td>3</td><td>p.meta</td><td><code>&lt;p class="meta"&gt;</code> (nicht <code>&lt;div&gt;</code>)</td></tr>
<tr><td>4</td><td>Emojis</td><td>Keine im Body</td></tr>
<tr><td>5</td><td>Dateiende</td><td>Endet mit <code>&lt;/html&gt;</code></td></tr>
<tr><td>6</td><td>Meta im Body</td><td>Keine doppelte Datum·Lesezeit-Zeile</td></tr>
<tr><td>7</td><td>Quellen-Überschrift</td><td>Kein <code>&lt;h2&gt;Quellen&lt;/h2&gt;</code></td></tr>
<tr><td>8</td><td>Links target</td><td>Alle mit <code>target="_blank"</code></td></tr>
<tr><td>9</td><td>Meta-Description</td><td>Vorhanden und nicht leer</td></tr>
<tr><td>10</td><td>QC-Zeile</td><td>In <code>&lt;p class="qc"&gt;</code></td></tr>
<tr><td><strong>11</strong></td><td><strong>BGG-Autorencheck</strong></td><td><strong>Designer gegen BGG verifizieren</strong></td></tr>
<tr><td style="color:#991b1b;font-weight:600;">12</td><td style="color:#991b1b;font-weight:600;">XML-API-Referenzen</td><td style="color:#991b1b;font-weight:600;">Keine "XML API" / "Betriebsgeheimnis"</td></tr>
<tr><td style="color:#991b1b;font-weight:600;">13</td><td style="color:#991b1b;font-weight:600;">Quellen verlinkt</td><td style="color:#991b1b;font-weight:600;">Quellen-Block hat <code>&lt;a href&gt;</code> Links</td></tr>
</tbody>
</table>
<p><strong>Fehlerbehandlung:</strong></p>
<ul>
<li><span class="badge badge-green">Exit 0</span> → Stage 4</li>
<li><span class="badge badge-red">Exit 1</span> → Korrigieren, erneut verify → max 3 Versuche → ABBRUCH, an Basti melden</li>
<li>CHECK 11 (BGG-Autoren) <span class="badge badge-yellow">Warnung</span> → dokumentieren, nicht blocken</li>
</ul>
<h3>STAGE 4: Deliver</h3>
<p><span class="badge badge-blue">Basti</span></p>
<ol>
<li>Git-Commit: <code>git add artikel_NAME.html && git commit -m "artikel: THEMA"</code></li>
<li>Article-Server prüfen: Direkt-URL testen<br>
<code>curl "http://185.162.249.159:8890/artikel_NAME.html?key=…" | head -3</code></li>
<li>Meldung:</li>
</ol>
<pre><code>✅ Artikel THEMA fertig
📄 /home/hermes/workspace/artikel_NAME.html
🔗 http://185.162.249.159:8890/artikel_NAME.html?key=…
📊 verify: 0 Fehler</code></pre>
<h2>4. Fehlermodi & Recovery</h2>
<table>
<tr><th>Fehler</th><th>Erkennung</th><th>Recovery</th></tr>
<tr>
<td>PDF nicht OCR-bar</td>
<td>pymupdf wirft Exception</td>
<td>Basti manuell OCRen, Text in Prompt geben</td>
</tr>
<tr>
<td>Quelle nicht erreichbar</td>
<td>curl/web_extract Timeout/404</td>
<td>5-Stufen-Eskalation:<br>curl → wget+UA → Wayback → Tavily → Google Cache</td>
</tr>
<tr>
<td>Keine AAA-Quelle für Kern-Fakt</td>
<td>Research-Gap</td>
<td>Fakt streichen → "unvollständig" an Basti</td>
</tr>
<tr>
<td>verify_article.sh fail</td>
<td>Exit ≠ 0</td>
<td>3 Korrekturversuche → Abbruch</td>
</tr>
<tr>
<td>BGG-Autorencheck uneindeutig</td>
<td>check_authors.py Warnung</td>
<td>Dokumentieren, Basti entscheidet</td>
</tr>
<tr>
<td>Article-Server down</td>
<td>curl auf :8890 Timeout</td>
<td>Server neu starten via <code>python3 article_server.py &</code></td>
</tr>
</table>
<h2>5. Cronjob-Integration</h2>
<p>Der Workflow läuft als One-Shot-Cronjob mit <code>deliver="local"</code>:</p>
<pre><code>cronjob(
action="create",
schedule="1m",
repeat=1,
deliver="local",
skills=["journalistic-article-writing", "korrekturschleife", "article-management"],
enabled_toolsets=["web", "terminal", "file", "search", "skills", "delegation"],
prompt="…" // Stage-0-Output
)</code></pre>
<p><strong>Wichtig:</strong> <code>deliver="local"</code> — der Cronjob meldet sich NICHT bei Daniel. Basti pollt das Ergebnis.</p>
<h2>6. Batch-Modus</h2>
<p>Für mehrere Artikel: Parallele Cronjobs (max 3 gleichzeitig via <code>delegation.max_concurrent_children</code>). Jeder Cronjob bekommt denselben Prompt-Aufbau, nur mit anderem Input.</p>
<h2>7. Was Cody bauen muss</h2>
<h3>7.1 <code>article_pipeline.py</code> — Orchestrator-Script</h3>
<ul>
<li>Input entgegennimmt (JSON oder CLI-Args)</li>
<li>Stage 0 ausführt (PDF-OCR, Prompt-Bau)</li>
<li>Zwei <code>delegate_task</code>-Aufrufe (Stage 1 Research, Stage 2 Write+QC)</li>
<li>Stage 4 ausführt (Git-Commit, Verify)</li>
<li>Exit-Code zurückgibt</li>
</ul>
<h3>7.2 Integration</h3>
<ul>
<li>Als Cronjob-Script lauffähig (<code>no_agent=false</code> Modus)</li>
<li>ODER: Als Hermes-Skill <code>article-pipeline</code> registrierbar</li>
</ul>
<h3>7.3 Config</h3>
<table>
<tr><th>Element</th><th>Pfad / Wert</th></tr>
<tr><td>Workspace</td><td><code>/home/hermes/workspace/</code></td></tr>
<tr><td>verify_article.sh</td><td><code>/home/hermes/workspace/verify_article.sh</code></td></tr>
<tr><td>article_server.py</td><td><code>/home/hermes/workspace/article_server.py</code></td></tr>
<tr><td>PDF-Cache</td><td><code>~/.hermes/cache/documents/</code></td></tr>
<tr><td>Skills</td><td>journalistic-article-writing, korrekturschleife, article-management</td></tr>
</table>
<h2>8. Aufruf-Beispiele</h2>
<pre><code># Variante A: Thema + PDF
python3 article_pipeline.py \
--topic "Gamegenic wird Partner von Tolarian Community College" \
--pdf "/home/hermes/.hermes/cache/documents/GG_Press_release.pdf" \
--rubric "Nachrichten" \
--category-id 9
# Variante B: Nur Thema (autonome Recherche)
python3 article_pipeline.py \
--topic "Neue Kennerspiel-Nominierungen 2026" \
--rubric "Nachrichten"
# Variante C: Batch
python3 article_pipeline.py --batch topics.json</code></pre>
<h2>9. Erfolgskriterium</h2>
<div style="background:linear-gradient(135deg,#d1fae5,#a7f3d0);border-radius:10px;padding:1.5rem;margin:1.5rem 0;text-align:center;">
<p style="font-size:1.1rem;margin:0;"><strong>🎯 Basti gibt ein Thema ein → nach ~10 Minuten liegt ein Artikel im Workspace mit</strong></p>
<p style="font-size:1.4rem;font-weight:700;color:#065f46;margin:0.3rem 0;">verify_article.sh: 0 Fehler</p>
<p style="font-size:0.9rem;color:#555;margin:0;">Kein manuelles Eingreifen. Kein Nachbessern. Kein "XML API v2".</p>
</div>
<hr>
<h2>Anhang: Skills-Dokumentation</h2>
<p>Folgende Skills werden im Workflow verwendet. Cody muss ihre Schnittstellen kennen:</p>
<table>
<tr><th>Skill</th><th>Typ</th><th>Funktion</th></tr>
<tr>
<td><code>journalistic-article-writing</code></td>
<td>Writing</td>
<td>HTML-Template, Quellenregeln, Sprachregeln, Formatvorgaben</td>
</tr>
<tr>
<td><code>korrekturschleife</code></td>
<td>QC</td>
<td>Zweistufiger Workflow (Write + Fact-Check), Writer-Fehler-Tabelle, Quellenbewertung AAA/AA/A</td>
</tr>
<tr>
<td><code>article-management</code></td>
<td>Deploy</td>
<td>Article-Server (Port 8890), Joomla-API, verify_article.sh, VG-Wort</td>
</tr>
</table>
</article>
<footer>
<p>Spezifikation für Cody · 23. Juni 2026 · brettspiel-news.de Redaktion</p>
</footer>
</body>
</html>