CommunityCodierung & Entwicklunggithub.com

chrislacey89/pre-merge

Primärer Pipeline-Review-Schritt nach der verifizierten Implementierung. Wird verwendet, um einen PR mit Linienverlauf zu erstellen und eine Architektur-Review vor dem Merge durchzuführen. Nicht für QA-Erfassung, Planung oder Implementierungsarbeit geeignet.

Was ist pre-merge?

Der Skill `/pre-merge` ist ein zentraler Review-Schritt in der Entwicklungs-Pipeline, der nach der verifizierten Implementierung und vor dem Merge in den Hauptzweig ausgeführt wird. Er analysiert den vollständigen Diff anhand der architektonischen Prinzipien des Projekts und erstellt einen GitHub-Pull-Request mit vollständiger Rückverfolgung zu PRD- und Slice-Issues. Der Skill erzeugt berichtende Ergebnisse und blockiert nicht den Merge, er repariert oder erstellt keine Issues – alle Befunde sind Empfehlungen. `/pre-merge` läuft in drei Modi: Author-Mode (Default), Reviewer-Mode und Loop-Mode. Der Author-Mode erstellt den PR und gibt Ergebnisse als temporäre Berichte aus, während der Reviewer-Mode Entwurfskommentare für einen PR erstellt, den der Benutzer nicht selbst verfasst hat. Der Loop-Mode protokolliert alle Befunde in einem dauerhaften Register, sodass sie auch sitzungsübergreifend erhalten bleiben. Der Skill unterstützt sowohl GitHub-Issues als auch eine Sidecar-Backend-Struktur (Work-Items), passt den Umfang der Analyse intelligent an und erkennt automatisierte Wiederholungsläufe. Er vermeidet Standardfehler wie die Ausgabe eines „sauberen“ Reviews bei trivialen Diffs – der Loop-Mode beendet sich nur, wenn alle Befunde einen Besitzer haben, nicht wenn die Anzahl der Befunde null ist. Der Skill ist ideal für Teams, die Code-Qualität und Architekturkonformität vor dem Merge systematisch und wiederholbar sicherstellen möchten, ohne den Workflow durch automatische Änderungen zu unterbrechen.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor✓Gemini CLI
npx skills add https://github.com/chrislacey89/skills/tree/HEAD/pre-merge

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Was macht pre-merge?

Erstellen Sie einen GitHub-PR, der auf das PRD und die Slice-Issues verweist, und überprüfen Sie den vollständigen Diff anhand der architektonischen Prinzipien des Projekts. Erzeugt beratende Ergebnisse – blockiert den Merge nicht, behebt Code nicht automatisch und erstellt keine Issues.

Aufrufposition

Dies ist ein primärer Pipeline-Skill, der nach der Verifikation der Implementierung und vor dem Merge in den Hauptzweig oder beim Übernehmen der PR-Review einer anderen Person verwendet wird.

Verwenden Sie /pre-merge, wenn der Zweig bereit für die PR-Erstellung, Architektur-Review und finale Plan-Code-Abstimmung ist. Verwenden Sie /pre-merge --pr <nummer>, wenn Sie einen PR überprüfen, den Sie nicht selbst verfasst haben.

Nicht als Ersatz für Implementierungsverifikation, QA-Erfassung oder Refactoring-Planung verwenden. Es wird vorausgesetzt, dass die Arbeit bereits erstellt und überprüfungsbereit ist.

Modi

/pre-merge läuft in einem von drei Modi. Alle drei verwenden die architektonischen Review-Dimensionen aus review-checklist.md erneut; sie unterscheiden sich darin, was sie konsumieren und was sie produzieren.

  • Author-Mode (Standard) – wird auf Ihrem eigenen Zweig ohne --pr-Argument aufgerufen. Der Skill erstellt den PR (Phase 2) und gibt die Ergebnisse als Beratungen im Terminal aus (Phase 4), danach wird die Kontrolle zurückgegeben – er erstellt keine eigenen Fix-Commits und öffnet keinen zweiten Durchlauf. Dies ist der Modus, der automatisch von /execute Schritt 6 auf dem HITL-Pfad aufgerufen wird. Was gelesen wird, wird durch den Zweigzustand bestimmt, nicht durch ein Flag: Eine erste Überprüfung liest das gesamte Slice, also den gesamten Zweig, es sei denn, der Arbeitseintrag des Slices zeichnet den Startpunkt auf; ein Wiederholungslauf gegen einen PR, der bereits einen Review-Currency-Stempel trägt, dessen Head sich inzwischen weiterbewegt hat, nimmt das Delta nach dem Stempel – die Commits nach dem gestempelten SHA – als Prüfgegenstand und liest nicht noch einmal, was die vorherige Prüfung abgedeckt hat. Phase 1 Schritt 4 trifft diese Entscheidung und gibt sie aus. Das Delta ist der Gegenstand, nicht die Grenze dessen, was ein Prüfer lesen darf: review-checklist.md legt fest, was ein Prüfer liest, und das umfasst den Baum um das Delta herum.
  • Reviewer-Mode – wird als /pre-merge --pr <nummer> gegen einen PR aufgerufen, den Sie nicht selbst verfasst haben. Der Skill überspringt die PR-Erstellung (der PR existiert bereits) und erstellt Entwurfskommentartext (Phase 4), den Sie überprüfen und posten können, strukturiert gemäß references/comment-craft.md (5P-Gate, Triple-R, Comment-Signale, MMG-Austausch).
  • Loop-Mode – wird als /pre-merge --loop aufgerufen oder automatisch betreten, wenn /execute die Kontrolle bei einem AFK-Lauf übergibt. Führt die Phasen 1–4 wie der Author-Mode aus, mit Ausnahme der Umfangsentscheidung in Phase 1 Schritt 4: Der Loop-Mode liest immer den gesamten Zweig und nimmt nie das Delta nach dem Stempel, fährt dann mit Phase 5 fort: Er zeichnet jeden Befund in einem dauerhaften Register auf – im PR-Text oder im Arbeitseintrag, wie references/state-backend.md § Wo die Aufzeichnungen des Reviews leben –, fügt die Belege bei, die jeden Befund stützen oder widerlegen, und übergibt die Kontrolle an den Operator. Befunde sind in diesem Modus keine Terminalausgabe mehr; sie werden zu dauerhaften Zeilen mit Besitzern. Der Loop-Mode repariert nichts und erstellt keine Commits – der Operator entscheidet, was mit jedem Befund geschieht (siehe Phase 5 § Warum der Loop nicht repariert).

Die Beendigungsbedingung des Loop-Modes ist, dass jeder Befund einen Besitzer hat – niemals, dass das Review sauber zurückkam. „Null Befunde“ ist ein verbotenes Terminationssignal, konsistent mit der bestehenden Mindestbefundzahl-Sperre in Phase 4, die geschrieben wurde, weil ein fast leeres Review bei einem nicht-trivialen Diff bedeutet, dass das Review vorzeitig endete, anstatt dass der Code fehlerfrei ist. Ein Loop, der bei sauberen Reviews terminiert, wird zuverlässig saubere Reviews produzieren und sonst nichts (Meadows, Seeking the Wrong Goal; Leveson: belohne niemals niedrige Vorfallzahlen – belohne die Meldung selbst).

Wenn Sie auf einem anderen Zweig als dem Arbeitszweig des Benutzers laufen und --pr nicht angegeben wurde, fragen Sie einmal nach, ob der Benutzer den Reviewer-Mode gegen eine bestimmte PR-Nummer meint, anstatt zu raten – automatische Erkennung spart einen Tastendruck, aber eine falsche Modusklassifizierung erzeugt Entwurfskommentare, die lokale Beratungen gewesen wären oder umgekehrt.

Wann zu verwenden

  • Author-Mode: nachdem QA bestanden wurde und vor dem Mergen eines Feature-Zweigs in den Hauptzweig; nachdem Ralph die AFK-Ausführung beendet hat und Sie das Verhalten verifiziert haben; oder für jeden Zweig, der vor dem Merge überprüft werden soll, auch ohne vollständigen Pipeline-Lauf.
  • Reviewer-Mode: wenn ein Teammitglied oder externer Mitarbeiter einen PR eröffnet und Sie die vollständige Architekturprüfung aus review-checklist.md auf seinen Diff anwenden und konstruktiven Kommentartext erstellen möchten.
  • Loop-Mode: wenn Befunde die Sitzung überdauern müssen, die sie erzeugt hat – die AFK-Übergabe von /execute oder jeder Zweig, den Sie über mehrere Sitzungen hinweg überprüfen und nicht jedes Mal neu ableiten möchten. Verwenden Sie ihn, wenn die Kosten, die Sie zahlen, darin bestehen, Befunde zu verlieren, nicht darin, die Korrekturen durchzuführen.

Ausführungsablauf

Phase 1: Kontext sammeln

Author-Mode:

  1. Fragen Sie nach der PRD-Issue-Nummer. Akzeptieren Sie „keine“, wenn diese Änderung nicht den gesamten Pipeline-Durchlauf durchlaufen hat. Wenn der Loop-Mode von einer AFK-/execute-Übergabe betreten wurde, fragen Sie nicht – übernehmen Sie die Issue-Nummer aus der Übergabe (/execute Schritt 6 übergibt sie) und behandeln Sie deren Fehlen als „keine“. Es gibt niemanden, der antworten kann, daher würde eine bedingungslose Frage den Lauf an seinem ersten Schritt aufhängen. Auf dem Sidecar-Backend ist die Antwort eine W-<n>-Arbeitseintrags-ID (Schritt 2). „Keine“ lässt Phase 2 nichts zum Aufzeichnen des PRs, und die Review-Notizen sowie das Loop-Mode-Register haben kein Zuhause: references/state-backend.md § Wo die Aufzeichnungen des Reviews leben, sagt, was mit ihnen geschieht.

  2. Falls ein PRD angegeben wurde:

    gh issue view <number>
    gh issue list --search "in:body #<prd-number>" --state all --json number,title,state,body --limit 100
    

    Analysieren Sie die Grenzkarten (Abschnitte Produziert/Konsumiert) aus den Texten der einzelnen Slice-Issues.

    Auf dem Sidecar-Backend (bash "$SC" backend slices antwortet sidecar, gemäß references/state-backend.md; der Block unten fragt es ab und stoppt bei einer Ablehnung, anstatt auf gh issue zurückzufallen), sind das PRD und seine Slices Arbeitseinträge, und die in Schritt 1 angefragte Nummer ist eine W-<n>-ID: das Slice, das dieser Zweig implementiert (das /execute übergibt), oder sein PRD. Es wird kein gh issue-Befehl ausgeführt; der Linienverlauf und die Grenzkarten stammen von den Arbeitseinträgen:

    SC="<dieses Skills Verzeichnis>/references/sidecar.sh"
    W="W-<n>"
    case "$(bash "$SC" backend slices)" in
      sidecar) ;;
      github) echo "backend ist github: Lesen Sie den Linienverlauf mit dem Issue-Block oben"; exit 0 ;;
      *) echo "Linienverlauf abgebrochen: sidecar.sh backend slices fehlgeschlagen; nicht den github-Pfad raten" >&2; exit 1 ;;
    esac
    J="$(bash "$SC" work view "$W" --json)" || { echo "Linienverlauf abgebrochen: $W kann nicht gelesen werden" >&2; exit 1; }
    case "$(jq -r '.kind // empty' <<<"$J")" in
      slice) PRD="$(jq -r '.parent // empty' <<<"$J")" ;;
      prd)   PRD="$W" ;;
      *) echo "Linienverlauf abgebrochen: $W hat keine Art" >&2; exit 1 ;;
    esac
    SLICES="$W"
    if [ -n "$PRD" ]; then
      bash "$SC" work view "$PRD" --json | jq -r '"# \(.id) (prd, \(.state))\n\(.body)"'
      SLICES="$(bash "$SC" work list --kind slice --parent "$PRD" --state all)" \
        || { echo "Linienverlauf abgebrochen: Die Slices von $PRD können nicht aufgelistet werden" >&2; exit 1; }
    fi
    while IFS= read -r S; do
      [ -n "$S" ] || continue
      bash "$SC" work view "$S" --json | jq -r '"# \(.id) (slice, \(.state))\n\(.body)"'
    done <<<"$SLICES"
    

    Analysieren Sie die Grenzkarten aus diesen Texten genau wie aus Issue-Texten. Behalten Sie $W: Phase 2 zeichnet den PR darauf auf.

  3. Erkennen Sie den Basis-Zweig und beurteilen Sie den Diff:

    SC="<dieses Skills Verzeichnis>/references/sidecar.sh"
    # $BASE_REF ist der Bereichsendpunkt; $BASE_BRANCH ist der Name, den `--base` akzeptiert.
    BASE_REF="$(bash "$SC" base-ref)" || { echo "base-ref fehlgeschlagen: Keine Basis erraten" >&2; exit 1; }
    BASE_BRANCH="$(bash "$SC" base-ref --name)" || { echo "base-ref --name fehlgeschlagen: Keine Basis erraten" >&2; exit 1; }
    git diff "$BASE_REF...HEAD" --stat
    git log --oneline "$BASE_REF..HEAD"
    

    base-ref gibt das deklarierte base_ref des Sidecars aus, wenn vorhanden, andernfalls die Voreinstellung origin/HEAD. Bei einem Exit-Code ungleich Null gibt es keinen Ref aus: Anhalten und stderr weiterleiten, anstatt eine Basis zu raten. Für ein Stacked-PR-Slice erreicht keine hier gesetzte Variable einen späteren Block: Fügen Sie den Zweignamen des Geschwister-Slices (das Upstream, auf das der PR abzielt) in den Platzhalter BASE_BRANCH= jedes Blocks ein, der ihn konsumiert (der Phase-2-Block für Ihr Backend und der Phase-4-Stempelblock). Wenn kein Diff vom Basis aus, teilen Sie dem Benutzer mit, dass es nichts zu überprüfen gibt, und stoppen Sie.

    Rest: $BASE_REF ist nur so aktuell wie das letzte git fetch. Wenn origin/<base> nicht aufgelöst wird, misst base-ref gegen den lokalen Zweig und sagt dies auf stderr; wenn die Zahlen falsch aussehen, führen Sie git fetch und erneut aus.

  4. Entscheiden Sie den Umfang – das gesamte Slice oder das Delta nach dem Stempel. Diese Entscheidung gilt nur für den Author-Mode. Der Loop-Mode überspringt sie und setzt SCOPE_FROM="$BASE_REF" bedingungslos, wobei er bei jedem Aufruf den gesamten Zweig liest, gemäß dem Loop-Mode-Punkt von Phase 3. Eine erste Überprüfung liest das gesamte Slice: sidecar.sh range gibt sein linkes Ende an, das der aufgezeichnete Start des Slices ist, wenn der in Schritt 2 benannte Arbeitseintrag noch einen auf diesem Zweig hat, andernfalls $BASE_REF, sodass auf dem github-Backend ein Slice der gesamte Zweig ist. Ein Wiederholungslauf gegen einen PR, den dieser Skill bereits gestempelt hat, dessen Head sich seitdem weiterbewegt hat – eine /fix-findings-Runde oder eine manuelle Korrektur nach einem absichtlichen Löschen der Sperre – nimmt das Delta nach dem Stempel als Gegenstand. Der Stempel lebt dort, wo backend stamp sagt, gemäß references/state-backend.md: im PR-Text oder im Sidecar. Lesen Sie den PR-Text mit demselben Ausdruck wie /closeout Schritt 2; scripts/test-review-currency-marker.sh pinnt die beiden byte-identisch, und scripts/test-delta-review-scope.sh führt diesen Block gegen eine Fixtur für jeden von ihm genannten Zweigzustand auf beiden Backends aus:

    SC="<dieses Skills Verzeichnis>/references/sidecar.sh"
    case "$(bash "$SC" backend stamp)" in
      sidecar)
        REVIEWED_SHA=$(bash "$SC" stamp read "$(git branch --show-current)") ;;
      github)
        REVIEWED_SHA=$(gh pr list --head "$(git branch --show-current)" --json body -q '.[0].body // ""' \
          | sed -n 's/.*<!-- reviewed-at: \([0-9a-f]\{40\}\) -->.*/\1/p' | tail -1) ;;
      *) echo "Umfang abgebrochen: sidecar.sh backend stamp fehlgeschlagen; nicht den github-Pfad raten" >&2; exit 1 ;;
    esac
    W="<die W-<n> aus Schritt 2, oder leer auf dem github-Backend>"
    BASE_REF="$(bash "$SC" base-ref)" || { echo "Umfang abgebrochen: sidecar.sh base-ref fehlgeschlagen" >&2; exit 1; }
    RANGE="$(bash "$SC" range ${W:+"$W"})" || { echo "Umfang abgebrochen: sidecar.sh range fehlgeschlagen" >&2; exit 1; }
    SLICE_FROM="${RANGE%%..*}"
    SCOPE_FROM="$SLICE_FROM"
    if [ -n "$REVIEWED_SHA" ] \
      && git merge-base --is-ancestor "$REVIEWED_SHA" HEAD 2>/dev/null \
      && [ "$REVIEWED_SHA" != "$(git rev-parse HEAD)" ] \
      && [ -z "$(git log --merges --format=%H "$REVIEWED_SHA..HEAD")" ]; then
      SCOPE_FROM="$REVIEWED_SHA"
    elif [ -n "$REVIEWED_SHA" ] \
      && ! git merge-base --is-ancestor "$REVIEWED_SHA" HEAD 2>/dev/null \
      && [ "$(git rev-parse -q --verify "$REVIEWED_SHA^{tree}")" = "$(git rev-parse 'HEAD^{tree}')" ]; then
      SCOPE_FROM="HEAD"
    fi
    if [ "$SCOPE_FROM" = HEAD ]; then
      echo "Review-Umfang: keiner, nur-Historie-Umschreibung – HEAD trägt den Baum, der bei $REVIEWED_SHA überprüft wurde"
    elif [ "$SCOPE_FROM" = "$BASE_REF" ]; then
      echo "Review-Umfang: gesamter Zweig, ab $BASE_REF"
    elif [ "$SCOPE_FROM" = "$SLICE_FROM" ]; then
      echo "Review-Umfang: gesamtes Slice, ab $SLICE_FROM ($W's aufgezeichneter Start)"
    else
      echo "Review-Umfang: Delta nach Stempel, ab $SCOPE_FROM"
    fi
    git diff "$SCOPE_FROM...HEAD" --stat
    git log --oneline "$SCOPE_FROM..HEAD"
    

    Vier Zustände fallen auf das gesamte Slice zurück, jeder absichtlich: kein Stempel (eine erste Überprüfung oder ein manuell erstellter PR); ein Stempel, der kein Vorfahre von HEAD ist und dessen Baum HEAD nicht mehr trägt (der Zweig wurde umgeschrieben und der Inhalt hat sich mitgeändert, oder der überprüfte Commit ist verschwunden – /closeout nennt dies das stärkere Divergenzsignal, und es ist kein kleineres Review); ein Stempel gleich HEAD (nichts Neues zum Festlegen des Umfangs); und ein Merge-Commit nach dem Stempel (das Delta nach dem Stempel würde die eigenen Änderungen des Basis-Zweigs tragen, die niemand auf diesem Zweig geschrieben hat). Das gesamte Slice ist der gesamte Zweig, es sei denn, range hat einen aufgezeichneten Start gefunden, und wenn es einen findet, den ein Fold oder Rebase wegschrieb, sagt es dies auf stderr und antwortet $BASE_REF, ohne den Start jemals neu zu verankern. Die Entscheidung wird ausgegeben, damit die Terminalausgabe und der PR dasselbe darüber sagen, was gelesen wurde.

    Eine Umschreibung, die den überprüften Baum beibehalten hat, ist keine Divergenz. Wenn der gestempelte Commit kein Vorfahre von HEAD ist, aber lokal noch existiert und denselben Baum wie HEAD trägt, hat sich die Historie geändert und der Inhalt nicht: Der Fold, den Phase 4 bei der Übergabe anbietet (git rebase -i --autosquash), erzeugt genau dies. Der Block gibt review scope: none aus und setzt SCOPE_FROM="HEAD". Überspringen Sie Phase 3 und alles in Phase 4 außer dem Stempel, der bei HEAD neu stempelt, und dem Übergabemenü. Der Stempel zertifiziert den überprüften Inhalt, und ein Tree-Hash ist dieser Inhalt exakt. Wenn der gestempelte Commit lokal nicht verfügbar ist, kann der Baum nicht verglichen werden, und die Umschreibung nimmt den oben genannten Fallback auf den gesamten Zweig.

    Bei einem Delta-Wiederholungslauf ist das Delta der Gegenstand und der Baum ist immer noch lesbar. Informieren Sie jeden Phase-3-Prüfer über die Befunde, die die Commits nach dem Stempel angeblich schließen – die frühere Ausgabe in dieser Sitzung, das Register, wenn der Loop-Mode eines geschrieben hat (wie references/state-backend.md § Wo die Aufzeichnungen des Reviews leben, sagt), oder die Commit-Nachrichten selbst – mit den /fix-findings-Brecher-Verdikten, falls vorhanden, und mit der bash "$SC" profile-Ausgabe, wortwörtlich, die Phase 3s Vertrag jedem Prüfer übergibt. Die erste Frage pro Commit ist, ob der Fix seinen Befund an jedem Ort schließt, den der Befund genannt hat, was die Fix-Vollständigkeitsdimension ist; die zweite ist die Auswirkung auf die allgemeine Architektur, die das Review in der Session des Wiederholungslaufs in Bezug auf die Wirkung auf das Ganze liest. Die Dimensionen sind dieselben, die "review-checklist.md" definiert, aber die Leserichtung ist anders: Von den Befunden zur Architektur, nicht vom Code zu den Befunden.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

chrislacey89/closeout

Primary pipeline tail step after /pre-merge, when a reviewed PR is ready to land and you want the workspace back to a clean base. Use to merge, switch off the worktree before removing it, prune the merged branch, pull base, and verify a clean end state. Triggers on 'close out', 'merge and clean up', 'get back to a clean main/base', 'tear down the worktree'. Not for capturing lessons (that's /compound), or closing the PRD and any other open slices and research-artifact hygiene (that's the cleanup prose in SYSTEM-OVERVIEW Step 9).

chrislacey89/compound

Primary pipeline knowledge-capture step that closes the compounding loop. Capture a durable lesson in docs/solutions/ onto the open PR before /closeout merges (the default), or post-merge when the lesson only surfaces during/after merge. Use so future /research and /write-a-prd runs improve. Not for trivial edits with no reusable project-level learning, and not for the merge/teardown itself (that's /closeout).

chrislacey89/excavate

User-invoked side-route for onboarding to a legacy repo with no docs/solutions/, research archive, or written decisions. Mines the last 12 months of git history and, when gh is available, PR bodies and review threads, into ranked hotspots, cited recovered decisions, and a who-to-ask map, then offers a PR of docs/solutions/ entries. Not for repos that already compound, not for judging people, not model-invoked.

chrislacey89/execute

Primary pipeline execution step after /prd-to-issues or for clearly scoped implementation work. Use to build, verify, and commit a concrete slice, delegating to /tdd for backend work and behavior-heavy frontend logic when red-green-refactor will reduce risk. Not for shaping or pre-merge review.

Verwandte Skills