CommunityCodierung & Entwicklunggithub.com

zheref/ao

Den Branch auf den aktuellen Stand des Basis-Branches bringen – Rebase, wenn nichts veröffentlicht wurde, Merge, wenn doch; mechanische Konflikte lösen und bei semantischen Konflikten mit beiden Seiten zur Prüfung anhalten.

Was ist ao?

Ao ist ein Skill für KI-Agenten (z. B. Claude Code, Cursor, Codex), der einen Feature-Branch gegenüber seinem Basis-Branch aktualisiert. Die Kernlogik unterscheidet zwischen „Text“ und „Bedeutung“: Mechanische Konflikte (z. B. in Lockfiles oder Changelogs) werden automatisch gelöst; semantische Konflikte, bei denen eine inhaltliche Entscheidung nötig ist, führen zu einem Stopp mit Darstellung beider Seiten – der Agent wählt nie eine Seite. Ao entscheidet automatisch zwischen Rebase (bei unveröffentlichten Commits) und Merge (bei bereits veröffentlichten), um Rewrites auf entfernten Branches zu vermeiden. Der Skill wird entweder eigenständig über `$ao [from <base>]` aufgerufen oder als Schritt in den Workflows von `$murasaki`, `$aka` und `$en` verwendet, nachdem die Kontextprüfung (WC-Klassifikation) und die eigentliche Aktualisierung (`nen wc catch-up`) durchlaufen wurden. Wichtig: Ao pusht niemals, forciert niemals und schreibt niemals einen bereits auf dem Remote befindlichen Commit um.

Funktioniert mit✓Claude Code✓Codex CLI~Cursor
npx skills add https://github.com/zheref/hatsu/tree/HEAD/surfaces/codex/ao

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

Gemeinsamer Richtlinien-Pfad: docs/DISCOVERY.md, docs/WORKFLOW.md, docs/LAUNCH-MIGRATION.md, docs/STANDALONE-ENTRY.md, docs/PROCESS.md, docs/using/README.md und docs/using/mirrors.md gehören zum aufgelösten Hatsu-Plugin-Root, nicht zum konsumierenden Repository. Auf einer installierten Oberfläche das absolute Root verwenden, das von ten ausgegeben wird, um diese Dateien zu lesen (falls nicht verfügbar, über diesen Skill neu auflösen). Relative Links unten identifizieren Quellorte; eine fehlende docs/-Kopie im Consumer ist keine fehlende Richtlinie und darf keine doppelte Meldung auslösen. Niemals eine zweite Richtlinie im Zielrepository kopieren oder erfinden.


Ao — der Branch, auf dem neuesten Stand

Wesen: Manipulator. Das Abgleichen eines Branches mit seiner Basis ist eine git-seitige Operation an einem Arbeitsstand, der nicht nur Ihnen gehört – unabhängig davon, welches Wesen den Diff erstellt hat.

Lege die Basis unter mich, löse, was nur Text ist, und gib mir alles, was Bedeutung hat.

Ao ist $murasakis erster Schritt, $akas dritter und der Schritt, den $en ausführt, wenn ein PR zurückfällt. Es ist auch allein aufrufbar. Die gesamte Disziplin besteht aus einer Unterscheidung – Text gegen Bedeutung – und einer Weigerung: Es pusht niemals, was es produziert hat.


0. Standalone-Einstieg – bereits vollständig

Ao liest bereits den Checkout, nicht einen Aufrufer. § 2 liest den Zustand vor allem anderen, § 3 entscheidet Rebase vs. Merge danach, ob etwas veröffentlicht wurde, und from <base> trägt die Basis mit nen/workflow.json → branch.base darunter. docs/STANDALONE-ENTRY.md § 4 führt es als bereits vollständig auf; die zutreffenden Klauseln sind P1 – $ten ao, wenn kein Composite es ausgeführt hat, fängt die Voraussetzungen dieser Phase ab (ten § 6) – und die Basis, die gegen die geholte origin/-Referenz aufgelöst wird, was § 3 bereits verlangt.

Durch einen standalone-Aufruf wird § 6 nicht abgeschwächt: Ein semantischer Konflikt ist ein G5-Stopp mit Darstellung beider Seiten, und er wird niemals durch die Wahl der Seite gelöst, die den Lauf fortsetzen würde. Ao pusht weiterhin nicht, forciert nicht und schreibt keine bereits auf dem Remote befindlichen Commits um.

Rückgabe. Als nächstes in der verketteten Ausführung: der Aufrufer, der den aktuellen Branch benötigte – $murasaki, $aka oder $en. Es wurde nichts gepusht, und Beweise, die vor diesem Update erhoben wurden, sind veraltet, wenn sich ein verfolgter Pfad geändert hat.


1. Aufruf

$ao [from <base>]
nen parse ao --grammar "from [<base>]" --line "<der Aufruf, minus das $ao-Präfix>"

Verifiziert live unter v0.3.0 (docs/ab/ao.md § 2.1): from release/1.4 → base: release/1.4; ein nacktes from wird ohne Klausel geparst, Exit 0. Die Klausel ist aus dem Grund hinter einem Literal verankert, den $spiritual-message § 1 festhält.

Ohne Klausel ist die Basis nen/workflow.json → branch.base, Standard main, wenn der Schlüssel oder die Datei fehlt. Nennen Sie die Basis laut, bevor Sie sie holen – ein Branch, der leise gegen die falsche Basis aktualisiert wurde, ist ein Diff, den danach niemand lesen kann.

Ein fehlendes Argument oder Konfigurationselement wird erfragt und inline eingerichtet (missing-argument, missing-configuration; WORKFLOW.md § 4 Fragen, einrichten, fortfahren).

2. Zuerst den Checkout auslesen

nen wc classify --repo <pfad> --base <base> --json

Verifiziert live unter v0.3.0 (docs/ab/ao.md § 2.2), --json trägt genau das, was dieser Skill benötigt, bevor er irgendetwas anrührt: state.branch, state.isTrunk, state.dirty, state.aheadOfBase, state.existingCommitSubjects[], state.uncommittedPaths[].

nen wc classify-FallWas ao tut
must-move – auf dem TrunkVerweigern. Es gibt nichts zu aktualisieren: Der Trunk ist die Basis. Das mitteilen und den Aufrufer an $breath oder $tensho übergeben, je nachdem, was die Situation verlangt
on-branch-dirtyVerweigern, unter Nennung der uncommitteten Pfade, die das Verb ausgegeben hat. Ein Merge oder Rebase über uncommittete Arbeit verweigert entweder bei git selbst oder vergräbt die Arbeit in einem Konflikt, den niemand entwirren kann. Committen ($kokusen) oder bewusst stashen, dann erneut ausführen
on-branch-cleanZu § 3 übergehen

nen wc classify ist kein Konfliktdetektor, und ein halbfertiger Merge wird als normale Arbeitsverzeichnis-Änderung gelesen – live verifiziert (docs/ab/ao.md § 2.2). Bei Ausführung innerhalb eines ungelösten Merges meldet es on-branch-dirty mit den konfligierenden Pfaden unter "uncommittete Pfade", ohne etwas über den laufenden Merge zu sagen. Also vor der Klassifizierung git nach einem fragen, niemals .git/ auf der Festplatte (in einem verlinkten Worktree ist .git eine Datei): git rev-parse -q --verify MERGE_HEAD, das auflöst, oder git rebase --show-current-patch, das mit 0 beendet (ein Rebase, der bei einem Patch gestoppt wurde: ein Konflikt oder ein edit-Stopp), bedeutet, dass eine vorherige Operation hier gestoppt hat, und dieser Lauf meldet diesen Zustand und startet nichts – niemals eine zweite Operation darauf und niemals ein erneuter Lauf von wc catch-up von hier, was einen Merge mit gits Standardnachricht und ohne erneuten Build (§ 5) committen würde. Die anderen Antworten der Abfrage: 1 (ein Rebase, der ohne aktuellen Patch pausiert, bei einem break oder einem fehlgeschlagenen exec) ist nicht aos, also meldet der Lauf es mit gits eigenem --continue / --abort und stoppt hier, niemals darauf vertrauend, dass catch-up es ablehnt, was ein Host, der noch auf nen 0.18.0 oder 0.18.1 läuft, nicht tut (zheref/hatsu#182); 128 ist kein Rebase, also klassifizieren; alles andere bleibt der unbeantworteten Abfrage-Reihe in § 3 überlassen.

3. Welche Operation – Rebase oder Merge, entschieden danach, ob etwas veröffentlicht wurde

Rebase, wenn nichts von diesem Branch veröffentlicht wurde. Merge, wenn etwas veröffentlicht wurde. Einen Commit umzuschreiben, den jemand anderes bereits geholt haben könnte, ist die eine git-Operation, die anderen Leuten Arbeit kostet, und die lokale Ebene führt sie niemals aus.

nen wc catch-up --repo <pfad> --base <base> [--strategy rebase|merge|auto] [--dry-run] [--json]

Das Verb holt zuerst, dann entscheidet, und die Entscheidung wird gegen das getroffen, was origin jetzt sagt, niemals gegen das, was dieser Checkout zuletzt gehört hat. auto (was ao übergibt) rebased, wenn nichts vom Branch auf @{upstream} ist, und merged sonst; --strategy rebase|merge benennt eine Strategie nur, wo der Aufrufer einen Grund hat, der laut ausgesprochen wird. Exit 0 meldet {base, strategy, before, after, behindBefore, aheadBefore, noOp}, und ein noOp: true wird trotzdem mit beiden SHAs gemeldet, niemals als "nichts zu tun". Jeder andere Exit, nach nen v0.20.0:

ExitWas es istao
1, mit einem Report, dessen conflicted[] nicht leer istein Konflikt; die Abbruchzeile wird ausgegeben§ 4 übernimmt
3, ein Report, dessen conflicted[]-Pfade alle im mechanical-Block der obersten Ebene von nen/contract.json (v0.20.0) sindein Konflikt, den nen als Manifest, Changelog oder Spiegel klassifiziert hat; die Abbruchzeile und die Befehle jeder Klasse werden ausgegeben, keiner ausgeführt§ 4 übernimmt, nens Klassen und Befehle als Beweis zitiert; § 4 klassifiziert trotzdem jeden Pfad selbst
1, kein Reportein Fetch-, Status- oder HEAD-Lese-Fehler, ein Rebase oder Merge ohne Konflikt fehlgeschlagen oder ein --continue fehlgeschlagenstoppen: nens stderr-Satz wörtlich zitieren, sagen, dass der Baum so ist, wie git ihn hinterlassen hat; niemals § 4
2, ein Rebase, der bei einem break oder einem fehlgeschlagenen exec pausiert (v0.18.2)nicht aos Rebasenens Satz zitieren, der git rebase --continue / --abort nennt; niemals fortsetzen oder abbrechen
2, ein Rebase-Probe, die git nicht beantwortet hat (v0.18.2)es könnte gar kein Rebase seinnens Satz zitieren und stoppen, ohne einen git-Befehl zu nennen
2, alles andereeine Verweigerung vor jeglicher Mutation: ein dreckiger Baum, ein --base, den git ablehnt, ein --strategy, das mit der laufenden Operation nicht übereinstimmt, ein zu altes git für --end-of-options, kein Repository-Rootwörtlich zitieren und stoppen
jeder andere Exitunerwartetstoppen und zitieren
  • strategy: merge → der Branch existiert auf dem Remote → die Basis wurde hereingemergt.
  • strategy: rebase → nichts veröffentlicht → der Branch wurde auf origin/<base> neu abgespielt.

Ein Rebase ohne etwas, worauf rebased werden soll, schreibt trotzdem die SHA um, und das ist erwartet. Live verifiziert: Ein Branch, der bereits direkt auf der Spitze von origin/<base> saß, antwortete mit "Erfolgreich rebased und aktualisiert" und bewegte HEAD von c8826c7 nach 84b0444 – gleicher Baum, gleiche Nachricht, neues Commit-Objekt, weil der Rebase den Commit erneut abspielt, anstatt zu bemerken, dass es nicht nötig ist. Es ist nur hier und ausschließlich hier harmlos: § 3 rebased nur einen unveröffentlichten Branch, also ist der umgeschriebene Commit einer, den niemand geholt hat. Es ist nicht harmlos, es als "nichts zu tun" zu melden – § 7 fragt nach der Basis und ihrer aufgelösten SHA, und ein Lauf, der keine Änderung sagt, während HEAD sich bewegt hat, hinterlässt jede spätere Referenz auf die alte SHA stillschweigend falsch.

Sagen Sie in einer Zeile, welche das Verb gewählt hat und warum, aus seinem Report, und nennen Sie die Aktualisierung: "origin geholt; der Branch ist auf @{upstream}, also strategy: merge, kein Rebase."

AUSGEMUSTERT bei nen 0.5, ersetzt bei 0.13. Die Merge-Hälfte lief über nen pr cascade-main --repo <pfad> --trunk <base> --no-push (live verifiziert unter v0.5.0, docs/ab/ao.md § Ausgemustert bei nen 0.5) und die Rebase-Hälfte hatte kein Verb bei irgendeinem Flag. Beide Hälften sind jetzt nen wc catch-up, das niemals pusht. cascade-main behält seine mutating-Zeile in izanamis Automatisierungstabelle, inklusive --no-push, und wird nicht mehr von ao aufgerufen.

4. Jeden konfligierenden Pfad klassifizieren, bevor einer gelöst wird

git -C <pfad> status --porcelain                    # die Konfliktzeilen
git -C <pfad> diff --name-only --diff-filter=U      # die konfligierenden Pfade, allein
git -C <pfad> ls-files -u                           # welche Stufen jeder Pfad hat

Live verifiziert gegen ein konstruiertes Fixture, das je eines trug (docs/ab/ao.md § 2.4):

PorzellanArtVorhandene Stufen
UUbeide-geändert – beide Seiten änderten dieselbe Datei1 Basis, 2 unsere, 3 ihre
AAhinzugefügt-hinzugefügt – beide Seiten erstellten denselben Pfad2 unsere, 3 ihre; keine Basis
UD / DUgelöscht-geändert – eine Seite löschte, was die andere bearbeitetenur die überlebende Seite
DD, AU, UAdie selteneren Formen; mit derselben Tabelle klassifizieren und benennenwie git sie meldet

nen wc catch-up --json trägt conflicted[] bei Exit 1 oder 3, einen Eintrag pro ungemergtem Pfad, mit ours und theirs wörtlich (und, ab nen.wc.catch-up/v0.2, nens class). Was es nicht trägt, ist die Art, also wird die Porzellan-Tabelle oben immer noch dafür gelesen, und § 6 zeigt ours/theirs genau so, wie das Verb sie ausgegeben hat. Die eigene Regel des Verbs ist die, die es wert ist, zitiert zu werden, wo sie landet: Es wählt niemals eine Seite.

Jeden Pfad klassifizieren, bevor einer von ihnen gelöst wird, und die Tabelle ausgeben. Ein Lauf, der die ersten drei löst und den vierten als semantisch entdeckt, hat bereits das Vertrauen des Maintainers in die ersten drei verspielt.

5. Mechanisch oder semantisch

Mechanisch – die Lösung ist bestimmt, vom Repository, nicht von jemandem gewählt:

  • ein Nur-Anhängen-Bereich, an den beide Seiten angehängt haben (ein Import-Block, eine .gitignore, eine Changelog-Liste) – beide behalten, in der Reihenfolge, die die eigene Konvention der Datei vorgibt;
  • eine generierte oder gesperrte Datei, die das Repository neu generiert (eine Lockfile, ein Snapshot, ein Spiegel) – die Seite der Basis nehmen und neu generieren (Hatsu-Spiegel: bash scripts/surface_mirror_regenerate.sh), dann mit dem deklarierten Build beweisen (nen shu build; die Exit-Tabelle ist $rasengan § 6);
  • eine reine Formatierungs- oder Leerraum-Abweichung ohne Verhaltensunterschied;
  • eine identische Änderung auf beiden Seiten.

Eine Hatsu-Versionskollision kann eine saubere Aktualisierung überleben: Parallele Branches könnten dieselbe Nummer gewählt haben. Nach jeder Aktualisierung beide tatsächlichen Manifeste (.claude-plugin/plugin.json und .codex-plugin/plugin.json) mit der frischen Basis vergleichen. Wenn die Version des Branches kleiner oder gleich der Basis ist, beide auf dieselbe Version streng über dieser Basis vor der Bereitschaft erhöhen; auch die Versionszeile im vorhandenen changelog.d/-Fragment dieses Aufwands aktualisieren. Dies ist Hatsu-Autorarbeit, kein automatisches nen wc catch-up-Erhöhen. Nachdem die nächste Version festgelegt wurde, bash scripts/plugin_version_refs.sh --from <alt> --to <neu> --body-file <lokaler-Entwurf> ausführen, um verfolgte Referenzen und Entwurfszeilen aufzulisten. --write hinzufügen, um deklarierte verfolgte Formen und jedes exakte alte Versionstoken in eindeutigen Entwurfszeilen umzuschreiben; die gedruckten review-Zeilen lesen, die unverändert bleiben. Der Helfer wählt niemals die Version, schreibt generierte Spiegel um oder bearbeitet einen Remote-PR. Die Spiegel mit dem obigen Befehl neu generieren, dann die durch die Aktualisierung ungültig gewordenen Body-Fakten aktualisieren:

Body-FaktNach der Aktualisierung neu ableiten
Plugin-Versiongit show HEAD:.claude-plugin/plugin.json und git show HEAD:.codex-plugin/plugin.json nach dem Commit der Erhöhung
Head- und Basis-Commitsgit rev-parse HEAD origin/<basis> nach dem letzten Commit und Fetch
Gegen die Basis gemessene Zahlen (Bytes, Diff, Abdeckung, Review-Evidenz)neu messen gegen diese frische Basis und den finalen Head
PR-Nummer in der Drive-Zeilegh pr list --repo <owner/name> --state open --head <branch> --json number,url; den zurückgegebenen aktuellen PR verwenden
Voraussetzungszeile des Changelog-Fragmentsneu messen gegen den aktualisierten Abhängigkeitsvertrag und die tatsächlichen Voraussetzungen dieses Aufwands

Den aktualisierten lokalen Entwurf überprüfen, dann nen pr edit-body als Remote-Schreiber verwenden. Die Erhöhungsprüfung gegen die frische Basis wiederholen; der ursprüngliche Branch-Punkt kann diesen Vergleich nicht beweisen.

Semantisch – alles, bei dem eine Person eine Absicht einer anderen vorziehen muss. UD/DU ist immer semantisch: "gelöscht" und "wird noch bearbeitet" sind zwei Überzeugungen darüber, ob ein Ding existiert, und kein Merge-Algorithmus hält die Überzeugung. Ebenso ein UU, bei dem beide Seiten dasselbe Verhalten geändert haben, und ein AA, dessen zwei Dateien nicht dieselbe Datei sind.

**Der Lehrbuchfall, live verifiziert (docs/ab/ao.md § 2.

Individual skills in this repo

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

Verwandte Skills