Explorar el Código

Make the update skill drive hermes plugins update, not a raw git pull

Deriving the remote instead of hardcoding it exposed the real shape of the
problem: the skill only ever described one of three installation classes, and
the class it described was not the one Hermes manages. There is no reason for
the skill to reach for git at all where a door already exists.

hermes plugins update does the pull *and* the bookkeeping around it: it clears
stale bytecode from the pre-update tree, records the new revision in the install
metadata, and asks before granting capabilities a new revision declares (fail
closed — without an answer they stay ungranted). A raw git pull leaves all three
behind, so Hermes keeps reporting a revision that is no longer the one on disk.
It also refuses in exactly the two cases worth stating, a pinned checkout and a
tree without .git, and a catalog install re-pins to the reviewed SHA instead of
pulling — which is why the skill now says "no git pull" outright rather than
offering it as an alternative.

The three classes are now a table an agent can act on instead of a path to
guess: installed by hermes (update), self-cloned (adopt once, then update), and
files copied by hand per README option B — which has no remote at all, cannot be
pulled, and cannot be faked into looking updatable. Reporting still needs git
(an old SHA to diff against), so fetch and the log stay, now with -C on every
command and with the two stand-ins tied to where each value comes from.

adopt is documented as one-time and self-cloned-only, because it refuses
otherwise, and "refuses" there reads as a failure unless the file says it means
"this case does not apply".
Paul Klumpp hace 2 semanas
padre
commit
64af4cf671
Se han modificado 1 ficheros con 59 adiciones y 42 borrados
  1. 59 42
      skills/chatto-plugin-update/SKILL.md

+ 59 - 42
skills/chatto-plugin-update/SKILL.md

@@ -1,7 +1,7 @@
 ---
 name: chatto-plugin-update
-description: "Use when a local Chatto plugin checkout maintained with git must catch up to its remote and the changes must go live in the running Hermes gateway."
-version: 1.1.0
+description: "Use when an installed Chatto plugin must catch up to its remote and the changes must go live in the running Hermes gateway."
+version: 1.2.0
 author: Paul Klumpp
 license: MIT
 metadata:
@@ -13,61 +13,74 @@ metadata:
 
 ## When to Use
 
-Ein lokaler Chatto-Plugin-Checkout, der mit **git gepflegt** wird, soll auf den
-Stand seines eigenen Remotes gebracht werden, und die Änderungen sollen im
-laufenden Hermes Gateway aktiv werden.
+Eine installierte Chatto-Plugin-Instanz soll auf den Stand ihrer Quelle
+gebracht werden, und die Änderungen sollen im laufenden Hermes Gateway aktiv
+werden.
 
 Der Remote steht hier bewusst **nicht**: er gehört der Installation, nicht dem
-Plugin. `git remote -v` des Checkouts ist die Wahrheit, und für einen
-selbst geklonten Checkout ist das ein privater Remote, den kein mitgeliefertes
+Plugin. `git remote -v` des Checkouts ist die Wahrheit, und für einen selbst
+geklonten Checkout ist das ein privater Remote, den kein mitgeliefertes
 Dokument kennen kann.
 
-**Nicht anwendbar auf eine per `hermes plugins install` installierte Instanz.**
-Deren Checkout gehört Hermes, nicht dem User; dort ist `hermes plugins update
-chatto-platform` der Weg (Schritt 2b). Ein `git pull` darin umgeht die
-Install-Metadaten, die den eingespielten Stand festhalten.
+## Schritt 1: Wo liegt die Instanz, und welche Art ist sie?
+
+Nicht raten — die drei Fälle haben verschiedene Türen, und zwei davon lassen
+sich nicht mit git bedienen:
+
+```bash
+ls -d ~/.hermes/plugins/chatto-platform \
+      ~/.hermes/plugins/platforms/hermes-chatto-plugin 2>/dev/null
+REPO=<der existierende Pfad>
+[ -d "$REPO/.git" ] && echo "hat git" || echo "kein git"
+```
+
+| Befund | Art | Tür |
+| --- | --- | --- |
+| `~/.hermes/plugins/chatto-platform/` mit `.git` und Provenance-Zeile | per `hermes plugins install` | `hermes plugins update chatto-platform` |
+| `~/.hermes/plugins/chatto-platform/` mit `.git`, ohne Zeile | selbst geklont | einmalig `hermes plugins adopt chatto-platform`, danach `hermes plugins update chatto-platform` |
+| `~/.hermes/plugins/platforms/hermes-chatto-plugin/` ohne `.git` | Dateien kopiert (README Option B) | **kein Pull möglich** — der User muss neu kopieren oder klonen |
+
+Im dritten Fall gibt es keinen Remote und kein `git log`: `hermes plugins update`
+verweigert hier ("no .git directory"). Das ist keine Störung, sondern der
+Zustand des Verzeichnisses — es zu umgehen hieße, den Zustand zu erfinden. Dem
+User sagen, dass er die Dateien neu holen muss, und dann bei Schritt 4
+weitergehen.
 
 ## Ablauf
 
-1. **Checkout auflösen.** Es gibt zwei dokumentierte Layouts; welches zutrifft,
-   lässt sich nicht raten, also prüfen:
+2. **Hermes-Tür benutzen, nicht git.** `hermes plugins update` ist der Weg, weil
+   es mehr tut als `git pull`:
    ```bash
-   ls -d ~/.hermes/plugins/chatto-platform \
-         ~/.hermes/plugins/platforms/hermes-chatto-plugin 2>/dev/null
+   hermes plugins update chatto-platform
    ```
-   `REPO` auf den existierenden Pfad setzen und **in allen folgenden Schritten
-   mit `git -C "$REPO"` arbeiten** — ohne das laufen die Kommandos im cwd der
-   Session, im schlimmsten Fall in einem fremden Repository.
-2. **Remote-Status PRÜFEN, nie behaupten:**
+   Es zieht den Stand, verwirft veralteten Bytecode aus `__pycache__`, schreibt
+   die neue Revision in die Install-Metadaten und fragt nach, wenn der neue Stand
+   Capabilities mitbringt, die noch nicht freigegeben sind (fail closed: ohne
+   Antwort bleiben sie nicht freigegeben). Zwei Fälle lehnt es ab und sagt es:
+   ein **gepinnter** Checkout (dann `hermes plugins install <quelle> --force
+   --ref <40-stelliger SHA>`) und ein Verzeichnis **ohne** `.git`. Ein Katalog-
+   Install wird auf die geprüfte SHA zurückgesetzt, nicht gepullt — deshalb hier
+   ausdrücklich kein `git pull`.
+3. **Statusbericht: erst fetchen, nie behaupten.** Für die Zusammenfassung in
+   Schritt 4 wird der alte Stand gebraucht, also **vor** dem Update abgreifen:
    ```bash
    git -C "$REPO" fetch --all
    git -C "$REPO" status -sb
    git -C "$REPO" branch -avv
-   git -C "$REPO" remote -v        # der Remote, von dem gepullt wird
-   ```
-   Erst fetchen, dann Sync-Status (ahead/behind) reporten. Aussagen wie
-   „synchron" nur NACH einem `fetch` — der lokale `status -sb` ohne fetch zeigt
-   ahead/behind nur gegen den zuletzt bekannten Remote-Stand. Aktueller Branch:
-   `git -C "$REPO" branch --show-current`. Den alten Stand aus `branch -avv`
-   ablesen und für Schritt 3 festhalten.
-3. **Zusammenführen.** Bei einem selbst geklonten Checkout: `git -C "$REPO" pull`
-   (Fast-forward). Bei Divergenz: mit dem User abklären, NICHT automatisch
-   mergen/rebasen.
-   Bei einer per `hermes plugins install` installierten Instanz stattdessen:
-   ```bash
-   hermes plugins update chatto-platform
    ```
+   Aussagen wie „synchron" nur NACH einem `fetch` — `status -sb` ohne fetch zeigt
+   ahead/behind nur gegen den zuletzt bekannten Remote-Stand. Den alten Commit
+   aus `branch -avv` ablesen und festhalten, nicht raten.
 4. **Commits zusammenfassen (Nutzersicht):**
    ```bash
    git -C "$REPO" log <alter_stand>..<neuer_stand>          # oneline
    git -C "$REPO" log <alter_stand>..<neuer_stand> --stat   # Datei-Umfang
    ```
-   `<alter_stand>`/`<neuer_stand>` sind aus Schritt 2 — den alten Stand dort
-   abgelesen, nicht geraten, sonst zeigt das Log einen leeren oder zu großen
-   Bereich. Commits haben ausführliche Messages — daraus eine
-   nutzerverständliche Zusammenfassung machen: WAS ändert sich für den
-   Bot-Nutzer, nicht Implementierungsdetails. Für jede Änderung eine Quelle
-   angeben (Commit-Hash).
+   `<alter_stand>` aus Schritt 3, `<neuer_stand>` aus Schritt 2 (der Revision, die
+   Hermes gemeldet hat, oder `HEAD` des Checkouts). Commits haben ausführliche
+   Messages — daraus eine nutzerverständliche Zusammenfassung machen: WAS ändert
+   sich für den Bot-Nutzer, nicht Implementierungsdetails. Für jede Änderung eine
+   Quelle angeben (Commit-Hash).
 5. **Gateway-Neustart ANBIETEN (nie selbst ausführen):** Plugin-Code-Änderungen
    werden erst nach einem Neustart des Hermes-Gateways aktiv — die laufende
    Session hält das alte Modul im Speicher.
@@ -91,13 +104,17 @@ Install-Metadaten, die den eingespielten Stand festhalten.
 
 ## Fallstricke
 
+- `git -C` in JEDEM git-Kommando. `git pull` oder `git log` ohne `-C` trifft den
+  Checkout der Session, nicht den Plugin-Checkout.
 - Aussagen über Sync-Status („synchron", „aktuell") NUR NACH `git fetch` treffen —
   ohne fetch ist der lokale Status wertlos.
-- **`git -C` in JEDEM Kommando.** `git pull` ohne `-C` trifft den Checkout der
-  Session, nicht den Plugin-Checkout.
+- `hermes plugins adopt` nur **einmal** und nur bei einem selbst geklonten
+  Verzeichnis. Hat Hermes bereits eine Provenance-Zeile, lehnt der Befehl ab
+  ("already has a provenance row") — das ist kein Fehler, sondern heißt: der
+  Fall greift nicht.
 - Vendored Updates (chattolib) kommen als dist-info-Rename + RECORD-Änderungen
-  im Pull — normal, und über den ganz normalen Neustart aus Schritt 5 hinaus
-  ohne Handlungsbedarf.
+  mit — normal, und über den ganz normalen Neustart aus Schritt 5 hinaus ohne
+  Handlungsbedarf.
 - Der Lifecycle-Guard prüft **den Inhalt** eines Skripts, sobald ein
   Shell-Interpreter es referenziert: `bash -n skript.sh` mit
   `hermes gateway restart` darin wird abgelehnt — auch unter einem anderen