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/executeSchritt 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.mdlegt 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 --loopaufgerufen oder automatisch betreten, wenn/executedie 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.mdauf 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
/executeoder 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:
-
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 (/executeSchritt 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 eineW-<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. -
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 100Analysieren Sie die Grenzkarten (Abschnitte Produziert/Konsumiert) aus den Texten der einzelnen Slice-Issues.
Auf dem Sidecar-Backend (
bash "$SC" backend slicesantwortetsidecar, gemäß references/state-backend.md; der Block unten fragt es ab und stoppt bei einer Ablehnung, anstatt aufgh issuezurückzufallen), sind das PRD und seine Slices Arbeitseinträge, und die in Schritt 1 angefragte Nummer ist eineW-<n>-ID: das Slice, das dieser Zweig implementiert (das/executeübergibt), oder sein PRD. Es wird keingh 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. -
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-refgibt das deklariertebase_refdes Sidecars aus, wenn vorhanden, andernfalls die Voreinstellungorigin/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 PlatzhalterBASE_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_REFist nur so aktuell wie das letztegit fetch. Wennorigin/<base>nicht aufgelöst wird, misstbase-refgegen den lokalen Zweig und sagt dies auf stderr; wenn die Zahlen falsch aussehen, führen Siegit fetchund erneut aus. -
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 rangegibt 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 demgithub-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, wobackend stampsagt, gemäß references/state-backend.md: im PR-Text oder im Sidecar. Lesen Sie den PR-Text mit demselben Ausdruck wie/closeoutSchritt 2;scripts/test-review-currency-marker.shpinnt die beiden byte-identisch, undscripts/test-delta-review-scope.shfü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
HEADist und dessen BaumHEADnicht mehr trägt (der Zweig wurde umgeschrieben und der Inhalt hat sich mitgeändert, oder der überprüfte Commit ist verschwunden –/closeoutnennt dies das stärkere Divergenzsignal, und es ist kein kleineres Review); ein Stempel gleichHEAD(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,rangehat 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
HEADist, aber lokal noch existiert und denselben Baum wieHEADträ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 gibtreview scope: noneaus und setztSCOPE_FROM="HEAD". Überspringen Sie Phase 3 und alles in Phase 4 außer dem Stempel, der beiHEADneu 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 derbash "$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.