Files
werkrevisor/docs/konzept-pr-lens-diagramme.md
claude-code db2fba45e7
werkator build succeeded after 00:09
werkator/werkrevisor-statistics build succeeded after 00:47
werkator/release build succeeded after 00:16
werkrevisor 0.52.0: diagrams of PR Lens in the result comment (#121)
See docs/prs for the PR document.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Reviewed-on: #121
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-18 20:57:15 +02:00

8.9 KiB
Raw Permalink Blame History

Konzept: Diagramme von PR Lens im Review-Kommentar

Stand: 2026-10-18, Übergabe aus einer Sitzung im Repo hsadmin-ng; noch nichts umgesetzt.

Ziel

werkrevisor macht das Review weiter allein. Zusätzlich hängt es an seinen Review-Kommentar ein Architektur- und Datenfluss-Diagramm des PR. Das Diagramm hilft dem menschlichen Reviewer zu sehen, was ein PR berührt. Die Risiko-Triage von werkrevisor verbessert es nicht direkt.

PR Lens

PR Lens von Coldtea erzeugt animierte Diagramme zu einem PR; der Kern ist MIT-lizenziert: github.com/coldteadotai/pr-lens.

  • Die GitHub-App macht Diagramm und Review, unterstützt aber nur GitHub, GitLab und Bitbucket, kein Gitea.
  • Das CLI-Kommando analyze liest den Diff gegen die Merge-Base, fragt ein LLM und schreibt .pr-lens/graph.json. Anbieter: gemini (Standard), openai oder openai-compatible mit eigener Base-URL. Nur analyze ruft ein Modell auf.
  • Das Format von graph.json beschreibt packages/schema.
  • @coldtea/pr-lens-renderer (npm, ohne Abhängigkeiten) macht aus graph.json animierte SVGs, hell und dunkel, und ein Manifest.
  • Für GitLab lädt PR Lens die SVGs als Anhänge ins Projekt hoch, für Bitbucket in die Downloads; für Gitea gibt es nichts Fertiges.

Das Review von PR Lens brauchen wir nicht, es deckt sich mit werkrevisor.

Was werkrevisor schon hat

  • werkrevisor/gitea.py: create_issue_comment, create_review und edit_issue_comment mit GITEA_TOKEN. Der Client sendet bisher nur JSON.
  • OpenRouter als LLM-Zugang, für hsadmin-ng mit openrouter/anthropic/claude-sonnet-5.5 (config/hsadmin-ng.toml). OpenRouter ist OpenAI-kompatibel; analyze kann es also mit openai-compatible nutzen.

Zwei Betriebsarten

  • git.javagil.de: werkrevisor läuft als Build in Werkator und kommentiert selbst; hier ist der volle Ablauf unten möglich.
  • dev.hostsharing.net: dort läuft nur hs-review auf der Workstation; es schreibt einen Entwurf, nur lesend, und der Mensch stellt die Befunde selbst ein. Die Schritte 3 und 4 entfallen; hs-review legt die SVGs neben den Entwurf, und der Mensch hängt sie beim Einstellen an.

Möglicher Ablauf

  1. graph.json erzeugen, nach Variante A oder B.
  2. pr-lens-renderer erzeugt die SVGs.
  3. werkrevisor legt den Review-Kommentar an und lädt die SVGs mit POST /repos/{owner}/{repo}/issues/comments/{id}/assets (multipart) hoch.
  4. werkrevisor ergänzt den Kommentar per edit_issue_comment um die Bildlinks.

Variante A: werkrevisor ruft pr-lens analyze mit OpenRouter als openai-compatible auf. Der Prompt von PR Lens bleibt in Gebrauch; das kostet aber einen zweiten LLM-Aufruf je Review.

Variante B: Das Review-LLM liefert graph.json im selben Lauf mit. Das ist günstiger, und der Diff geht an kein zweites Modell. Dafür müssen wir den Prompt für das Schema selbst schreiben und pflegen.

Grenzen des Diagramms

Das Diagramm ist nur eine Sichthilfe, keine Aussage darüber, was der PR tut. In beiden Varianten geht der Inhalt des PR in den Prompt. Ein gezielt gebauter PR kann so ein harmlos wirkendes Diagramm erzeugen, das z. B. einen Abfluss von Daten verschweigt; die Messung vom 2026-10-17 zeigt, dass ein solcher Abfluss in einer passenden Datei leicht übersehen wird. Der Kommentar sagt das beim Diagramm in einem Satz.

Neue Abhängigkeiten

  • Node.js für CLI und Renderer. Das ist eine neue Technik und braucht eine eigene Entscheidung des Menschen, mit den Alternativen, z. B.:
    • Node.js nur in einem Container, nicht auf dem Host;
    • den Renderer nach Python portieren, er hat keine Abhängigkeiten;
    • nur Variante B, dann braucht es analyze nicht.
  • Multipart-Upload im GiteaClient.
  • Kein neuer Token, falls der Upload mit derselben Berechtigung write:issue geht wie das Kommentieren.

Lieferkette

werkrevisor läuft wie pull_request_target und hält GITEA_TOKEN und den Schlüssel für OpenRouter.

  • Die npm-Pakete laufen mit festen Versionen und Prüfsummen, in einem Container ohne GITEA_TOKEN.
  • analyze bekommt nur den Schlüssel für OpenRouter, der Renderer keinen Schlüssel und kein Netz.
  • Mit npm werden npm audit und license-checker Pflicht-Prüfungen im Build (siehe agentic-workflow).

Offene Fragen

  • TODO.svg: Lässt [attachment] ALLOWED_TYPES auf dev.hostsharing.net und git.javagil.de SVG-Anhänge zu? Ja, auf beiden; aber höchstens 5 Dateien je Kommentar (max_files), bei 100 MB je Datei.
  • TODO.anzeige: Zeigt Gitea ein angehängtes SVG im Kommentar mit Animation an, oder nur als Download? Inline und animiert; Gitea liefert image/svg+xml mit einer CSP, die Skripte sperrt.
  • TODO.zugriff: Sind Anhänge privater Repos nur für angemeldete Benutzer mit Leserecht sichtbar? Ja; ohne Anmeldung kommt 404.
  • TODO.token: Reicht write:issue des Bot-Tokens für den Upload? Mit dem Token von claude-code geht es; das Bot-Token hat keinen Zugriff auf werkrevisor-bench. Das erste eingeschaltete Repo zeigt es; ein fehlendes Recht gibt nur eine Zeile im Log.
  • TODO.dateien: Höchstens 5 Anhänge je Kommentar, PR Lens macht je Diagramm 2 SVGs. Nur die helle Fassung, höchstens max_diagrams = 5.
  • TODO.variante: Variante A oder B; dafür Kosten und Qualität an einigen hsadmin-ng-PRs messen. Variante A, entschieden am 2026-10-18 nach dem Versuch unten.
  • TODO.schalter: Wie heißt der Schalter je Repo in der Konfiguration, und gilt er als Standard aus? [diagrams] enabled, nur in der Host-Konfiguration, Standard aus.
  • TODO.grenzen: Was passiert bei großen Diffs oder einem Fehler von analyze? Ein fehlendes Diagramm darf das Review nie beenden und das Ergebnis nicht ändern. Der Diff wird nach max_diff_bytes abgeschnitten; ein Fehler oder eine Zeitüberschreitung gibt nur eine Zeile im Log.

Versuch von Hand, 2026-10-18

Ohne Änderung an werkrevisor, für hsadmin-ng PR#319 (Tarife am Partner, 36 Dateien, +1489 −13):

  • @coldtea/pr-lens-cli@0.13.2 in node:22 unter Podman; MIT, 4 Abhängigkeiten, npm audit ohne Befund.
  • analyze spricht nur mit dem genannten Anbieter; prlens.dev nur bei canvas und auth.
  • analyze --provider openai-compatible --base-url https://openrouter.ai/api/v1 --model anthropic/claude-sonnet-5.5, nur mit OPENROUTER_API_KEY im Container: 174 KB Prompt (etwa 45k Token), 35 s, 15 Knoten, 16 Kanten, 2 Abläufe.
  • render ohne Netz: 3 Diagramme (Architektur, 2 Abläufe), je hell und dunkel; keine Skripte, keine externen Verweise.
  • Inhalt brauchbar: Controller, Tarif-Domäne, neuer Trigger und neue Tabelle, mit NEW und CHANGED markiert.
  • Upload mit POST /repos/{owner}/{repo}/issues/comments/{id}/assets und Bildlinks per Edit: werkrevisor-bench Issue 89.

Variante B, nachgestellt mit einem eigenen Skript: ein Aufruf mit kurzer Review-Anweisung, dem System-Prompt von PR Lens, Schema und Diff; die Antwort ist {"review": …, "graph": …}.

  • 71k Token Eingabe, 5,3k Ausgabe, 31 s, 0,195 USD.
  • graph gültig im ersten Versuch: 11 Knoten, 14 Kanten, 2 Abläufe; die Abläufe zeigen auch die 400-Fälle.
  • Das Review daneben ist brauchbar: 5 Befunde mit Datei und Zeile.

Kosten je Review mit anthropic/claude-sonnet-5.5 (2 USD je 1M Token Eingabe, 10 USD je 1M Ausgabe):

Variante Zusatzkosten Grund
A etwa 0,21 USD Diff und Anweisungen ein zweites Mal, dazu etwa 7k Token Ausgabe
B etwa 0,10 USD nur Anweisungen und Schema (etwa 15k Token) und die Ausgabe

Haken an B: werkrevisor fragt das Review-Modell über PR-Agent 0.47.0; dessen Antwort ist ein festes YAML-Format, extra_instructions ändern es nicht. B im selben Lauf heißt also, in PR-Agent einzugreifen, oder einen eigenen Aufruf neben PR-Agent; der eigene Aufruf ist aber Variante A mit eigenem Prompt. Für das Rendern braucht B weiter Node.js, außer der Renderer wird portiert.

Entscheidung, 2026-10-18

Variante A, mit dem Diff aus der Gitea-API statt einer Arbeitskopie: werkrevisor/pr_lens.mjs nutzt Prompt, Schema und Prüfung des festgelegten PR Lens. Node.js und PR Lens liegen im schreibgeschützten Basis-Archiv, nicht in einem Container: die Sandbox von werkdock auf mih09 hat keine Container-Laufzeit. nvm im Konto mih09-werkator hilft nicht: die Sandbox sieht es nicht, und das Toolchain-Home, das sie einbindet, können normale PR-Builds beschreiben. Der Kindprozess bekommt nur den Schlüssel für OpenRouter; er könnte als derselbe Benutzer aber die Umgebung von werkrevisor aus /proc lesen. Je Host abschaltbar, Standard aus. Auf git.javagil.de hängt werkrevisor die hellen SVGs an seinen Kommentar; hs-review folgt in einem eigenen PR.

Nächster Schritt

Umsetzung in werkrevisor PR#121; siehe docs/prs/2026-10-18-PR#121-pr-lens-diagrams.md und docs/DECISIONS.md.