Was macht closeout?
Nehmen Sie einen überprüften PR und setzen Sie den Arbeitsbereich auf eine saubere Basis zurück: Mergen, die Shell aus dem Worktree entfernen, bevor dieser gelöscht wird, den gemergten Branch bereinigen, den Basis-Branch pullen und den Endzustand überprüfen. Dies ist das Ende der Pipeline: die am häufigsten wiederholte Aktion ("Ich bin fertig, merge es und bring mich zurück zu einem sauberen Main") wurde aus dem Kopf des Benutzers in eine Fähigkeit verlagert.
Warum Dies Existiert
/execute Schritt 0 erstellt einen Worktree für jeden Slice; bis diese Fähigkeit existierte, hat nichts einen entfernt. Worktrees sind ein Bestand mit Zufluss und ohne Abfluss, daher steigt der Bestand unbegrenzt an (Meadows, Thinking in Systems — der strukturelle Ausweg für einen Bestand mit Zufluss ohne Abfluss besteht darin, die fehlende Rückkopplungsschleife hinzuzufügen, nicht stärker zu appellieren). Die Merge → Teardown → Pull-Sequenz existierte nur im Gedächtnis des Benutzers, und "prospektives Gedächtnis versagt still" (Norman, The Design of Everyday Things — verlagern Sie das Wissen aus dem Kopf in die Welt). Die Reihenfolge ist wirklich fehleranfällig: das Entfernen eines Worktrees, während das aktuelle Arbeitsverzeichnis der Shell noch darin ist, lässt die Shell in einem gelöschten Verzeichnis zurück, und ein von node_modules abhängiger Stop-Hook, der von dort aus ausgelöst wird, erzeugt eine Flut falscher MODULE_NOT_FOUND "Lint-/Type-Fehler", die wie eine echte Regression aussehen. Die Reihenfolge "cd zum Basis-Pfad vor dem Entfernen" in Schritt 4 ist die tragende Reparatur für genau diesen Fehler.
Diese Fähigkeit orchestriert vorhandene Werkzeuge (gh pr merge, wt remove / git worktree remove, commit-commands:clean_gone). Sie führt keinen neuen Dateisystemzustand ein. Sie überprüft das Ergebnis — sauberer Arbeitsbaum, auf einer neuen Basis, PR gemergt — nicht nur, dass die Bereinigung ausgeführt wurde (Meadows' "das falsche Ziel suchen": ein Closeout, das danach bemessen wird, ob es "ausgeführt wurde", optimiert den Proxy und erzeugt zerbrechliches Rituál).
Aufrufposition
Dies ist eine primäre Pipeline-Fähigkeit, die das Merge → Cleanup-Ende des Standard-Auslieferungspfades besitzt:
… → /pre-merge → /compound (im PR, wenn eine Lektion existiert) → /pre-merge (erneuter Durchlauf über den Compound-Commit; erneutes Stempeln) → [Merge + Worktree-Abbau — DIESE FÄHIGKEIT] → [Issue-Schließen — Schritt 9 Prosa]
Verwenden Sie /closeout, wenn:
/pre-mergeeinen PR erstellt hat und die Überprüfung abgeschlossen ist (oder die Änderung trivial genug ist, um keine zu benötigen)- der PR genehmigt und mergebar ist und Sie ihn gemergt und den Arbeitsbereich auf eine saubere Basis zurückgesetzt haben möchten
- der Benutzer bat, "abzuschließen", "zu mergen und aufzuräumen", "den Worktree abzubauen" oder "zurück zu einem sauberen Main/Base zu kommen"
Verwenden Sie /closeout nicht, wenn:
- der PR noch nicht erstellt oder noch in der Überprüfung ist — führen Sie zuerst
/pre-mergeaus - Sie eine dauerhafte Lektion erfassen möchten — das ist
/compound, das standardmäßig bereits auf dem PR geritten ist, bevor/closeoutmergt (Post-Merge/compoundist der Fallback);/closeouterfasst keine Lektionen - Sie das PRD und Slice-Issues schließen oder die Frontmatter des Research-Artefakts abgleichen möchten — das ist die Bereinigungssprache in
SYSTEM-OVERVIEW.mdSchritt 9;/closeoutführt die Git-Hygiene-Hälfte durch und verschiebt die Issue-schließende und Research-Artefakt-Ablösungs-Hälfte auf Schritt 9, anstatt sie zu duplizieren. Der einzige von ihm geschlossene Eintrag ist der Arbeitsgegenstand des gemergten Slices imsidecar-Backend (Schritt 3), weil dort keineCloses #N-Zeile dies beim Merge erledigt - die Änderung überhaupt nicht auf einem Feature-Branch ist (Sie sind auf dem Basis-Branch mit nichts zu mergen) — es gibt nichts abzuschließen
Es ist HITL-bestätigt und nicht blockierend: es operationalisiert ein bereits optionales Ende. Es führt niemals automatisch einen Merge durch — ein Merge ist nach außen gerichtet und schwer rückgängig zu machen, daher bestätigt es immer zuerst.
Ablauf
Führen Sie dies als eine "Do-Confirm"-Checkliste (Gawande) aus: führen Sie jeden Schritt aus, überprüfen Sie dann sein Ergebnis vor dem nächsten. Die destruktiven Schritte (4–6) sind selbstschützend — bestätigen Sie die Sicherheitsvorbedingungen in Schritt 2, bevor Sie sie ausführen.
0. Host-bereitgestellte Isolation? Bereinigung abgeben
Bestimmen Sie vor der Merge-/Teardown-Sequenz, ob die Isolation dieses Repos host-eigen ist (Conductor, Codespaces, Devcontainers). Wenn dies der Fall ist, führt /closeout weiterhin den GitHub-nativen Merge durch, baut aber weder den Worktree ab noch bereinigt es den lokalen Branch — der Host besitzt diese Hälfte des Lebenszyklus, und dagegen anzukämpfen ist Meadows' Politik-Resistenz (zwei Akteure, die denselben Bestand pushen). Geben Sie den Worktree-Bestand an den Host ab.
Die Abflusserkennung ist strenger als die Zuflussprüfung von /execute und darf nicht allein die generische Heuristik "toplevel ≠ primärer Arbeitsbaum" verwenden: ein pipeline-erstellter Worktree erfüllt diesen Test ebenfalls, daher kann das generische Signal nicht unterscheiden, ob "der Host den Teardown besitzt" oder "die Pipeline hat dies erstellt und muss es abbauen". Lösen Sie dies aus .claude/settings.json worktree.provisioning auf (Standard "auto", wenn nicht vorhanden) und beachten Sie eine explizite Überschreibung an diesem Ende genauso wie /execute beim Zufluss:
host— Teardown bedingungslos abgeben.pipeline— die Pipeline besitzt den Teardown. Führen Sie die vollständigen Schritte 4–6 unten aus, auch wenn eine Host-Umgebungsvariable vorhanden ist — eine explizitepipeline-Einstellung bedeutet, dass/executeden Worktree selbst bereitgestellt hat, daher muss/closeoutihn abbauen (das Verhalten vor dem Host). Eine Host-Umgebungsvariable überschreibt keine explizitepipeline-Wahl.auto(Standard) — Teardown nur dann abgeben, wenn eine Host-Umgebungsvariable diesen Baum beschreibt: der folgende Block gibthost_owned=yesaus. Niemals aufgrund des generischen Signals "toplevel ≠ primary" allein abgeben, und niemals aufgrund der bloßen Anwesenheit vonCONDUCTOR_WORKSPACE_PATH— eine unter Conductor gestartete Shell erbt diesen und kann einen tragen, der ein anderes Repositorys Workspace benennt, und das Abgeben auf dieser Basis hinterlässt einen pipeline-erstellten Worktree, den niemand abbauen kann.
# Host-Signal: Beschreibt eine Host-Umgebungsvariable DIESEN Baum, nicht nur diese Shell?
host_owned=no
top=$(cd "$(git rev-parse --show-toplevel)" && pwd -P)
if [ -n "${CONDUCTOR_WORKSPACE_PATH:-}" ]; then
ws=$(cd "$CONDUCTOR_WORKSPACE_PATH" 2>/dev/null && pwd -P) || ws=
if [ -n "$ws" ]; then
case "$top/" in "$ws"/*) host_owned=yes ;; esac
fi
fi
if [ -n "${CODESPACES:-}" ] || [ -n "${REMOTE_CONTAINERS:-}" ]; then host_owned=yes; fi
echo "host_owned=$host_owned"
Wenn der Teardown nicht abgegeben wird (einschließlich worktree.provisioning: "auto" mit host_owned=no), besitzt die Pipeline ihn — führen Sie die vollständigen Schritte 4–6 unten wie beschrieben aus.
Wenn die Isolation host-eigen ist, führt /closeout eine reduzierte Sequenz aus:
- Schritt 3 (Merge) läuft weiterhin vollständig —
gh pr merge --delete-branch. Conductor und ähnliche Hosts erstellen den PR, überlassen den Merge jedoch einer menschlichen Aktion; der von der Pipeline durchgeführte GitHub-native Merge ist der Mehrwert, den sie bietet, und der Host spiegelt das Ergebnis wider. Die Verschiebung beschränkt sich auf den Dateisystem-Teardown, niemals auf den Merge. - Schritt 4s Neuverankerung, Schritt 5s
wt remove/git worktree remove/ExitWorktree { remove }und Schritt 6s lokalen Branch-Bereinigung überspringen — der Host besitzt den Worktree- und Branch-Lebenszyklus (Conductor gibt sie frei, wenn der Workspace archiviert wird). Verwenden Sie niemals--forcegegen einen host-verwalteten Baum. - Schritt 8s Checkliste: „Worktree weg" und „Branch bereinigt" werden zu „N/V — host-verwaltet." Die Checks für Merge, sauberen Baum, PR-gemerkt und Remote-Branch gelten weiterhin. Der letzte ist einfach unter demselben N/V einzuordnen, ist es aber nicht: was der Host besitzt, sind der Dateisystem-Worktree und der lokale Branch, während der Remote-Branch durch das
gh pr merge --delete-branchgelöscht wird, das diese Fähigkeit weiterhin vollständig ausführt (siehe einen Aufzählungspunkt oben). Das Abgeben der Hälfte, die der Host besitzt, gibt nicht die andere Hälfte auf, die er nicht besitzt.
1. Absicht bestätigen und Zustand sammeln
Niemals automatisch mergen. Geben Sie an, was Sie tun werden, und holen Sie eine explizite Freigabe ein.
Sammeln Sie zuerst die Fakten (diese sind schreibgeschützt):
git branch --show-current # der Feature-Branch
git rev-parse --show-toplevel # der aktuelle Arbeitsbaum (kann ein Worktree sein)
git worktree list --porcelain | awk '/^worktree /{print $(2); exit}' # der BASE-Checkout (Haupt-Arbeitsbaum)
gh pr view --json number,title,url,state,mergeable,mergeStateStatus,reviewDecision 2>/dev/null
Bestimmen Sie den Basis-Branch, auf den der PR abzielt — den deklarierten Standard des Repos, keine Annahme:
SC="<Verzeichnis dieser Fähigkeit>/references/sidecar.sh"
bash "$SC" base-ref --name # der reine Branchname: prod, niemals origin/prod
Diese Stelle möchte den Basis-Branch Namen, keinen Ref — er füttert git switch <base-branch> in Schritt 4, und git switch lehnt einen Remote-Tracking-Ref kategorisch ab (fatal: a branch is expected, got remote branch 'origin/prod') — es will den lokalen Basis-Branch, den Sie gleich pullen werden. Daher fragt es base-ref --name und bewusst nicht die Ref-Form, die /pre-merge, /help, /walk-commits, /visual-recap, /compound und /execute nehmen; sie benötigen einen Ref nur, weil sie die Basis als Range-Endpunkt verwenden, was diese Fähigkeit niemals tut. Versuchen Sie nicht, dies anzupassen, um es an sie anzugleichen. Wenn base-ref --name mit einem Exit-Code ungleich Null beendet wird, wurde keine Basis gefunden: geben Sie seinen stderr aus und halten Sie an, anstatt eine zu raten.
Teilen Sie dem Benutzer in einem kurzen Block mit: welcher PR gemergt wird, welcher Worktree (falls vorhanden) und welcher Branch abgebaut wird und zu welchem Basis-Branch Sie zurückkehren und ihn pullen werden. Warten Sie auf Bestätigung. Wenn es auf diesem Branch keinen PR gibt, halten Sie an und leiten Sie zu /pre-merge weiter.
2. Sicherheitsvorbedingungen vor jedem destruktiven Schritt überprüfen
Der Teardown ist destruktiv; überprüfen Sie zuerst, ob er sicher ist (Selbstschutz). Alle folgenden Bedingungen müssen erfüllt sein:
- Der Feature-Branch ist vollständig gepusht —
git statuszeigt keine ungepushten Commits, undgit log @{u}..ist leer. - Ein PR für diesen Branch existiert und ist mergebar (
mergeableistMERGEABLE;mergeStateStatusist nichtBLOCKED/DIRTY). - Erforderliche Checks sind grün und die Überprüfung ist genehmigt (
reviewDecisionistAPPROVED, oder das Repo erfordert keine Überprüfung und der Benutzer hat explizit zugestimmt).
Wenn eine Vorbedingung fehlschlägt, halten Sie an und melden Sie, welche — mergen oder entfernen Sie nichts. Eine fehlgeschlagene Vorbedingung ist ein Signal, zur Überprüfung zurückzukehren, nicht durchzudrücken. Wenn die fehlgeschlagene eine Überprüfung ist — reviewDecision ist CHANGES_REQUESTED — ist der Weg zurück /respond-to-review: es überprüft jeden Kommentar gegen den Code, der Mensch entscheidet, was zu beheben und was zu widersprechen ist, und die Korrekturen durchlaufen /fix-findings und einen erneuten /pre-merge-Durchlauf, bevor /closeout erneut ausgeführt wird.
Aktualität der Überprüfung — deckt die Genehmigung noch diesen Diff ab? (nicht blockierend)
Die drei obigen Kontrollkästchen fragen, ob eine Überprüfung stattgefunden hat. Keines fragt, ob sie den Diff abdeckt, der gleich gemergt wird. Im beabsichtigten linearen Ablauf sind dies dieselbe Frage, was genau der Grund ist, warum die Lücke unsichtbar ist; in einer echten HITL-Sitzung wächst der Umfang auf einem Branch nach seinem Überprüfungsdurchlauf, und nichts verbindet den Diff, den /pre-merge gelesen hat, mit dem Diff, den /closeout mergt. Dies ist ein Zufluss ohne Rückkopplungsschleife (Meadows — die strukturelle Lösung besteht darin, die Schleife hinzuzufügen, nicht zu appellieren), und es verschlechtert leise „der PR wurde überprüft" zu „eine frühe Version des PR wurde überprüft" in dem einen Moment, in dem die Verschlechterung am meisten zählt. Continuous Delivery stellt die Regel klar: Das Artefakt, das Sie überprüfen, muss das Artefakt sein, das Sie ausliefern.
Lesen Sie den Stempel, den /pre-merge Phase 4 hinterlassen hat, und vergleichen Sie ihn mit dem aktuellen Kopf. Er befindet sich dort, wo backend stamp angibt, gemäß references/state-backend.md: im PR-Text oder im Sidecar.
git fetch --quiet
SC="<Verzeichnis dieser Fähigkeit>/references/sidecar.sh"
case "$(bash "$SC" backend stamp)" in
sidecar)
REVIEWED_SHA=$(bash "$SC" stamp read "$(git branch --show-current)")
HEAD_SHA=$(git rev-parse '@{u}' 2>/dev/null || git rev-parse HEAD) ;;
github)
REVIEWED_SHA=$(gh pr view <number> --json body -q .body \
| sed -n 's/.*<!-- reviewed-at: \([0-9a-f]\{40\}\) -->.*/\1/p' | tail -1)
HEAD_SHA=$(gh pr view <number> --json headRefOid -q .headRefOid) ;;
*) echo "closeout aborted: sidecar.sh backend stamp failed; not guessing the github path" >&2; exit 1 ;;
esac
Im Sidecar-Backend ist der Kopf der Upstream des Branches, was die Forge mergen wird: die erste Vorbedingung oben erfordert bereits, dass er mit dem lokalen Kopf übereinstimmt. Es fällt auf HEAD zurück, wenn der Branch keinen Upstream hat. stamp read gibt dieselbe vollständige 40-stellige OID aus, die der PR-Text-Marker trägt, oder nichts, also läuft alles unten unverändert auf beiden Backends.
Genau 40 hexadezimale Zeichen, verglichen durch String-Gleichheit. Beide Hälften dieses Satzes sind tragend, denn dieser Marker ist ein Vertrag, der zwei Fähigkeiten umspannt. /pre-merge Phase 4 gibt die vollständige 40-stellige OID aus, und headRefOid ist immer 40 Zeichen lang, daher ist \{40\} die einzige Breite, die jemals gleich verglichen werden kann — die Akzeptanz einer kürzeren würde es einem fehlerhaften Marker (einem handbearbeiteten Text, einem Templates-Platzhalter, der in die falsche Hälfte eingesetzt wurde) ermöglichen, erfolgreich zu parsen und dann für immer von $HEAD_SHA abzuweichen. [[ "$REVIEWED_SHA" == "$HEAD_SHA" ]] ist der Vergleich: exakte String-Gleichheit auf zwei vollständigen OIDs, niemals ein Präfixtest. Ein Marker, den der Regex zurückweist, ergibt einen leeren $REVIEWED_SHA und führt zum unten stehenden Zweig "kein Stempel gefunden", der sich anmutig verschlechtert — weit besser als der Zweig "SHAs unterscheiden sich", der auf einem PR Alarm schlägt, dessen Kopf sich nie bewegt hat. Im Skill-Kit-Repo fixiert scripts/test-review-currency-marker.sh diesen Rundlauf gegen beide Fähigkeiten, sodass das Format des Autors und dieser Parser nicht stillschweigend auseinanderdriften können.
Drei Ergebnisse, und nur eines unterbricht:
- Die SHAs stimmen überein — String-gleiche vollständige OIDs, daher ist der überprüfte Diff der Merge-Kandidat. Still bestehen. Beschreiben Sie es nicht: dies ist der häufigste Fall, und die Ankündigung eines Nicht-Ereignisses bei jedem Durchlauf ist das, was ein Tor zu einer Tapete macht.
- Kein Stempel gefunden (
$REVIEWED_SHAleer) — ein handverfasster PR, ein externer Beitrag, ein PR, der älter als der Stempel ist, oder ein Marker, dessen Form der obige Regex abgelehnt hat. Notieren Sie es in einer Zeile („kein/pre-merge-Stempel auf diesem PR — Aktualität der Überprüfung unbekannt") und fahren Sie fort. Das Fehlen eines Stempels ist kein Beweis für einen nicht überprüften Diff, und das Anhalten bei jedem nicht gestempelten PR ist genau die Alarmmüdigkeit, die ein Tor reflexartig überwinden lässt (Meadows, Politik-Resistenz). - Die SHAs unterscheiden sich — zwei wohlgeformte 40-stellige OIDs, die nicht String-gleich sind, was bedeutet, dass nach der Überprüfung Commits gelandet sind. Halten Sie nicht an,
…
[abgeschnitten für die Übersetzung]