seepuls/docs/CURATOR.md
Till JS f1af194a71 feat(venues): Event-Sources via Venue-YAML kuratierbar (venue-direkt zuerst)
Optionaler eventSource-Block (url + crawlIntervalHours) im Venue-YAML.
import-venues legt daraus idempotent eine inaktive scope='venue'-Source
an (deterministische ID es_yaml_<slug>) — Re-Import lässt active +
Crawl-State (failCount/Backoff) unangetastet, Reviewer-Aktivierung
bleibt also erhalten.

Strategie: venue-direkt zuerst (eigene Programmseiten, §87a-unkritisch,
self-hostbar), stadtweite Guidle-Discovery als bewusste 2. Phase.

Seed: 3 verifizierte Programm-URLs (zebra-kino /monatsprogramm,
kula /program, kult-x kultur.kult-x.ch). Aktivierung bleibt
Reviewer-Stop (probe -> active:true), wartet auf Service-Key (α-1c).
Doku in CURATOR.md + STATUS.md (α-3.7).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 16:15:21 +02:00

6.9 KiB
Raw Permalink Blame History

Curator-Workflow — Seepuls

Wie Inhalte in den Seepuls-Korpus kommen. Drei Skills, klare Reviewer- Stops, dieselbe Disziplin wie bei Cardecky und Zitare.

Cross-Repo-Pattern: ../mana/docs/CONTENT_PIPELINES.md ist die Single-Source-of-Truth für Pipeline-Patterns. Seepuls folgt dem dort dokumentierten 5-Stufen-Skelett (Plan → Recherche → Design → Validate → Publish) mit Reviewer-Stops nach Plan und Design.

Drei Skills

Skill Aufgabe SOT
/seepuls-curate-venue Venue anlegen oder erweitern YAML in apps/api/src/data/curated/venues/<slug>.yml
/seepuls-validate-venue Read-only-Check eines Draft-Venue (7 Findings)
/seepuls-curate-events Events einer Venue pflegen (Crawl-Mode + Manual-Mode) DB direkt (seepuls.events)

SOT-Wahl: warum Venues YAML, Events DB?

Aspekt Venues Events
Lebenszeit langlebig, ändern sich selten kurzlebig (verschwinden nach Datum)
Volumen 3080 realistisch 5005000
Audit-Trail git-getracktes YAML wertvoll DB-crawl_jobs reicht
Re-Import idempotent, ersetzt manuelle Korrekturen Dedupe-Upsert via external_id_hash
Curator-Disziplin jeder Eintrag will durchdacht sein Bulk-Streams, automatisch

Venues sind die wenigen handgepflegten Anker; Events fließen daran vorbei.

Workspace-Disziplin

Drafts leben außerhalb des Repos in ~/Documents/seepuls-drafts/<slug>/:

~/Documents/seepuls-drafts/
├─ museum-rosenegg/                   ← venue-draft
│  ├─ plan.md
│  ├─ research/{sources,notes}.md
│  ├─ design/venue.yml
│  ├─ validate/report.md
│  └─ publish/import.log
└─ museum-rosenegg-events-2026-06-15/  ← events-draft (datum-gestempelt)
   ├─ plan.md
   ├─ research/probe.json
   ├─ design/events.jsonl
   ├─ validate/report.md
   └─ publish/run.log

Vorteil: Audit-Trail bleibt, ohne den Repo aufzublähen. Re-Run nach Unterbrechung möglich.

Pflicht-Reviewer-Stops

Auch wenn der User „mach einfach" gesagt hat:

  1. Nach Plan-Stufe — Boundaries festklopfen, Slug bestätigen, Modus festlegen.
  2. Nach Design-Stufe — strukturierte Daten (YAML oder JSONL) als Markdown-Preview, ja/nein.
  3. Vor Publish — Compliance-Veto durch mana-compliance-Subagent bei sensiblen Inhalten.

Stops sind kurz und retten den Korpus vor Müll. Bei Bulk-Operationen reicht Sampling-Stop (510 zufällige Einträge + Streitfall-Liste).

Lizenz und Attribution

Venues und Events sind keine kreativen Schöpfungen — wir aggregieren öffentliche Veranstaltungs-Daten Dritter. Die Felder folgen daher der Aggregator-Policy, nicht der CC-Lizenz-Logik von Zitare oder Cardecky:

  • attributionRequired: true ist Default (sichtbare Quell-Domain im Frontend).
  • source.url + source.refs[] sind Pflicht für Audit + Take-Down.
  • Bilder via Hot-Link (siehe mana/docs/AGGREGATOR_POLICY.md §3).
  • Lebende Personen (Künstler:innen einer Veranstaltung) werden nur als Title-String erfasst, keine Personen-Profile.

Volle Policy: ../mana/docs/AGGREGATOR_POLICY.md.

Importer-Workflow

# Venue-YAML editieren oder via Skill anlegen, dann:
pnpm --filter ./apps/api db:import-venues

# Output: "X inserted, Y updated, 0 errors"
# Idempotent: zweiter Run = 0 inserted, X+Y updated

Bei Schema-Validierungs-Fehlern bricht der Importer mit exit 1 ab. Das YAML muss korrigiert werden, kein Auto-Fix.

Event-Source einer Venue mit-kuratieren

Optionaler Block im Venue-YAML — die eigene Event-/Programm-Seite der Venue (NICHT ein stadtweiter Sammelkalender, das ist scope='city' per Admin-API):

eventSource:
  url: 'https://zebra-kino.de/monatsprogramm/'
  # crawlIntervalHours: 24   # optional, 6..168, Default 24

Der Importer legt daraus idempotent eine scope='venue'-Source an (deterministische ID es_yaml_<slug>), inaktiv. Re-Import aktualisiert URL/Intervall, lässt aber active und den Crawl-State (failCount/Backoff) unangetastet — eine vom Reviewer freigegebene Source wird nicht zurückgesetzt.

Aktivierung bleibt manueller Reviewer-Stop (AGGREGATOR_POLICY):

POST /api/v1/admin/event-sources/<id>/probe   # Vorschau, kein DB-Write
PATCH /api/v1/admin/event-sources/<id>         # { "active": true }

robots.txt + Crawl-Delay des Event-Source-Hosts prüft die Pipeline zur Probe-/Crawl-Zeit automatisch.

Anti-Halluzinations-Regeln (kompakt)

  • Niemals Adressen oder Koordinaten raten — Nominatim oder Quellen-Beleg.
  • Niemals Description LLM-paraphrasieren — direkte Übernahme aus offizieller Quelle, ≤ 200 Zeichen.
  • Niemals Social-URLs erfinden — leer lassen wenn nicht auf der Website verlinkt.
  • Niemals Datum aus Free-Form raten — strict-ISO oder droppen.
  • Niemals Event ohne starts_at — kein Datum, kein Event.

Bulk-Mode

Erst ab größeren Mengen relevant:

  • Venues: ≥ 10 auf einmal (z.B. „alle Konstanzer Museen aus konstanz.de/tourismus"). Sampling-Stop auf 5.
  • Events: ≥ 30 auf einmal (z.B. ein Saison-Programm). Sampling-Stop auf 10 + alle Streitfälle (Datum unklar etc.).

Verhältnis zur automatischen Crawl-Pipeline

Seepuls hat zwei Wege, eine Venue/Events anzulegen:

  1. Skill-Pfad (manuell, dieser Workflow): /seepuls-curate-venue → YAML-SOT → Importer. Reviewer-Stops Pflicht.
  2. Crawl-Pfad (automatisch): POST /api/v1/admin/venues/from-url → mana-research → mana-llm → DB-row mit crawl_status='pending-review'. Reviewer löst die Pending-Review später per UI.

Beide schreiben in dieselbe seepuls.venues-Tabelle. crawl_status unterscheidet (manual-entry vs pending-review vs claimed). YAML-SOT existiert nur für manual-entry-Venues.

Offene Punkte

  • Venues aus Crawl-Pfad nach YAML-SOT migrieren: wenn ein pending-review-Eintrag vom Reviewer akzeptiert wird, sollte er optional ins YAML wandern (für git-getrackte Persistenz). Heute: manueller Export aus DB.
  • Events-Validator-Skill /seepuls-validate-events fehlt (analog /cards-validate-deck).
  • Wikidata-Anbindung für Venues — analog /zitare-curate-author Wikidata-Enrich. V2.
  • mana-compliance-Subagent muss für Venue/Event-Diffs sinnvolle Veto-Heuristiken haben (Werte: keine kommerzielle Werbung, keine Tracking-Wrapper, robots-Respect). Aktuell generischer Mission-Check.

Referenzen