Abgleich mit dem Vault-Stand 7f484f9

38 Datei(en) geändert.
Erzeugt von .vault-tools/auto-push/werkzeuge_spiegel.py.
This commit is contained in:
Pascal Michel committed 2026-11-02 03:00:03 +01:00
1 parent f5747605c7
commit 9e506ff588
38 files changed
+2325 -24

No files matched your search

+77
View File
@@ -0,0 +1,77 @@
---
type: resource
title: "Entwurf: Shell-Wache"
status: active
summary: "Entscheidungsliste, Herkunft je Antwort, Angriffsliste und Abbruchbedingung für shell_wache.py, einen PreToolUse-Hook auf das Bash-Werkzeug, der bei vier bekannten Windows-Shell-Fallen einen Hinweis in den Kontext gibt und nie ablehnt."
tags: [vault-tools, pruefwerkzeuge]
created: 2026-10-30
updated: 2026-10-30
---
# Entwurf: Shell-Wache
Angelegt am 2026-10-30 als Entwurfsschritt nach [[AI/Regelwerk/pruefwerkzeuge|pruefwerkzeuge.md]], Abschnitt 1. Anlass ist Befund S-14 des Workflow-Reviews: Bekannte Shell-Fallen kehren trotz Erinnerung wieder. Pascal hat einen Hook beschlossen; das Prüferurteil hat ihn auf maschinell eindeutige Muster und auf Warnen begrenzt. Die Regeln selbst stehen in [[AI/Regelwerk/windows-shell|windows-shell.md]].
Plan: [00-uebersicht.md](docs/plans/2026-10-30-shell-wache/00-uebersicht.md) · Codedoku: [shell_wache.md](docs/code/shell_wache.md)
## Entscheidungsliste
| # | Frage | Antwort | Herkunft |
|---|---|---|---|
| 1 | Welches Ereignis, welcher Matcher? | `PreToolUse`, Matcher `Bash` | **Projektvorgabe** — Pascal, Workflow-Review 2026-10-30, S-14 |
| 2 | Lehnt der Hook ab? | Nie. Kein `permissionDecision` in der Ausgabe: `allow` würde die Berechtigungsabfrage überspringen, `deny` und `ask` halten den Befehl an | **Projektvorgabe** — Prüferurteil S-14 („nur warnen“) |
| 3 | Welche Ausgabeform? | Exit 0. Mit Befund genau ein JSON-Objekt `{"hookSpecificOutput": {"hookEventName": "PreToolUse", "additionalContext": "…"}}`, ohne Befund keine Ausgabe | **Quelle** — Schema im Programmabbild von Claude Code 2.1.309: `hookEventName:C("PreToolUse"), permissionDecision…optional(), …, additionalContext:o().optional()`, gelesen 2026-10-30 mit `grep -a` |
| 4 | Welche Exit-Codes? | Immer 0, auch bei kaputter Eingabe und internem Fehler | **Quelle** — Hilfetext im selben Abbild: „Exit code 2 - show stderr to model and block tool call“; „Other exit codes - show stderr to user only“. Exit 2 wäre eine Ablehnung, andere Codes erreichten das Modell nicht |
| 5 | Woher kommt der Befehl? | `tool_input.command` der Hook-Eingabe auf stdin | **Quelle** — Hilfetext: „Input to command is JSON of tool call arguments“; das Feld `command` ist das Argument des Bash-Werkzeugs. Erst die Probe-Sitzung belegt die Form am echten Aufruf |
| 6 | Welche Muster? | Genau vier: `python -I` ohne `-X utf8`, `pkill` mit `-f`, `python3`, `bash` ohne Pfad im Windows-Kontext | **Projektvorgabe** — Auftrag nach S-14; Fallgeschichten in den Erinnerungen `python-isoliert-ignoriert-pythonioencoding`, `pkill-f-trifft-die-eigene-shell`, `bash-startet-unter-windows-den-wsl-stub` |
| 7 | Werden Heredoc-Backslashes geprüft? | Nein | **Projektvorgabe** — Prüferurteil S-14: Die Verfälschung passiert in der Werkzeugschicht und ist im Befehlstext nicht als Fehler erkennbar |
| 8 | Was ist „Windows-Kontext“ für `bash`? | (a) der Rest der Zeile hinter `cmd /c`, `cmd //c`, `cmd.exe /c`, `powershell`, `pwsh` (mit oder ohne `.exe`, mit oder ohne Pfad); (b) im ganzen Befehl ein Python-Listenelement `["bash"` oder `['bash.exe'` | **Projektvorgabe** — gemessen 2026-10-30 im Bash-Werkzeug: `type -a bash` liefert zuerst `/usr/bin/bash`; ein `bash` auf oberster Ebene der Git-Bash ist also die Git-Bash und bleibt still. Windows selbst sucht zuerst in `System32` (windows-shell.md) |
| 9 | Wann gilt `bash` als „mit Pfad“? | Steht direkt davor `/` oder `\`, bleibt es still | **Projektvorgabe** |
| 10 | Was ist eine Linux-Weiche? | Ein Wort `wsl`, `ssh`, `docker`, `podman` oder `kubectl` (mit oder ohne `.exe`). Im Windows-Kontext (a) bleibt ein `bash` hinter einer Weiche auf derselben Zeile still. `python3` und Muster (b) bleiben im ganzen Befehl still, sobald irgendwo eine Weiche steht | **Projektvorgabe** — dort läuft der Befehl unter Linux, wo `python3` und `bash` richtig sind |
| 11 | Wann ist `python -I` ohne `-X utf8`? | Je Aufruf von `python` oder `python.exe` (mit oder ohne Pfad): Optionen bis zum ersten Nicht-Optionswort lesen; `-c` und `-m` beenden die Optionen, auch in einem Bündel wie `-Ic`; `-W` und `-X` nehmen ein Argument, angehängt oder als nächstes Wort. Treffer, wenn `I` in einem Bündel steht und kein `-X utf8` oder `-X utf8=1` davor | **Quelle** — Python-Kommandozeile (`python --help`): `-I` schließt `-E` ein, `-c` und `-m` beenden die Optionsliste. **Projektvorgabe:** `-X utf8=0` zählt nicht als utf8 |
| 12 | Gilt das `-I`-Muster auch für `python3`? | Nein, dafür gibt es Muster `python3` | **Projektvorgabe** — ein Hinweis je Fehler |
| 13 | Wann ist `pkill` mit `-f`? | Hinter dem Wort `pkill` (mit oder ohne Pfad) die Optionswörter bis zum ersten Nicht-Optionswort: Treffer bei `--full` oder einem Bündel aus Buchstaben mit kleinem `f` (`-f`, `-fx`). `-u`, `-U`, `-g`, `-G`, `-P`, `-s`, `-t`, `-F`, `--signal` nehmen das nächste Wort als Argument. Auch in WSL und über ssh | **Quelle** — `pkill(1)`, procps-ng: `-f, --full`. **Projektvorgabe:** keine Weiche, weil die Falle gerade unter Linux zuschlägt; `pgrep -f` bleibt still, es beendet nichts |
| 14 | Was meldet der Hook bei kaputter Eingabe? | Einen Hinweis `[eingabe]` mit dem Grund (leer, kein JSON, kein Objekt, `tool_input` oder `command` fehlt oder hat den falschen Typ) | **Projektvorgabe** — pruefwerkzeuge.md, Abschnitt 6: eine fehlende Voraussetzung ist ein Befund |
| 15 | Was bei leerem `command`? | Still | **Projektvorgabe** — nichts zu prüfen, Abschnitt 6 |
| 16 | Was bei `tool_name` ungleich `Bash`? | Hinweis `[eingabe]`, nichts geprüft. Fehlt `tool_name`, wird trotzdem geprüft | **Projektvorgabe** — ein erweiterter Matcher soll laut auffallen, nicht mit falscher Kontextregel prüfen |
| 17 | Was bei einem internen Fehler? | Gefangen, Hinweis `[intern]` mit Ausnahmetyp, die bis dahin gesammelten Befunde stehen trotzdem im Text | **Projektvorgabe** — pruefwerkzeuge.md, Abschnitt 4 |
| 18 | Wie sieht der Hinweis aus? | Erste Zeile: „shell-wache warnt nur, der Befehl läuft trotzdem.“ Danach je getroffenem Muster genau eine Zeile mit Schlüssel in eckigen Klammern, Abhilfe und Verweis auf `AI/Regelwerk/windows-shell.md`, bei `pkill` zusätzlich auf die Erinnerung | **Projektvorgabe** |
| 19 | Groß- und Kleinschreibung? | `cmd`, `powershell`, `pwsh`, `bash`, `python` ohne Rücksicht darauf; `pkill` und seine Optionen genau | **Projektvorgabe** — Windows-Namen sind beliebig geschrieben, Linux-Optionen nicht |
| 20 | Wie liest das Skript stdin? | Als Bytes, Dekodierung UTF-8 mit Ersatzzeichen; Aufruf `python -I -X utf8` | **Projektvorgabe** — windows-shell.md, „Welche Shell, welches Python“ |
## Angriffsliste
Je Fall ein Treffer und ein gesunder Gegenfall; jeder Treffer einmal am Anfang und einmal am Ende des Befehls.
| Klasse | Fälle |
|---|---|
| fehlt | stdin leer; `tool_input` fehlt; `command` fehlt |
| null | `null` als ganze Eingabe, als `tool_input`, als `command` |
| falscher Typ | Liste statt Objekt; `tool_input` als Zeichenkette; `command` als Zahl und als Liste |
| leer | `command` gleich `""` (still) |
| zusätzlich | unbekannte Felder in Eingabe und `tool_input` (still); `tool_name` gleich `PowerShell` (Hinweis `[eingabe]`) |
| doppelt | dasselbe Muster zweimal in einem Befehl: eine Zeile |
| mehrere | alle vier Muster in einem Befehl: vier Zeilen |
| Wertebereich | `-IB`, `-BI`, `-Ic`, `-IX utf8`, `-Xutf8`, `-X utf8=0`, `-I` hinter `-c` oder hinter dem Skriptnamen; `pkill -TERM -f`, `pkill -fx`, `pkill --full`, `pkill -u root -f`; `python3.12`, `python3-config`; `bash.exe`, `.bashrc`, `bash_profile`, `bash-completion` |
| Reihenfolge | jedes Muster am Anfang und am Ende, dazu in Zeile 3 eines mehrzeiligen Befehls |
| Umgebung | ungültiges UTF-8 auf stdin; kein JSON; Aufruf ohne `PYTHONIOENCODING` |
## Abbruchbedingung
Schluss ist, wenn eine Prüfrunde nur noch Umformulierungen oder neue Fehlalarm-Grenzfälle in Zeichenketten findet. Fehlalarme kosten hier eine Zeile Kontext, keinen abgelehnten Befehl; sie werden als Lücke benannt, nicht wegprogrammiert.
## Benannte Lücken
- Erwähnungen in Zeichenketten schlagen an, etwa `grep "python -I" datei` oder eine Commit-Nachricht. Der Hook kennt keine Shell-Grammatik.
- Das PowerShell-Werkzeug ist nicht abgedeckt; dort ist jeder Befehl Windows-Kontext. Eine Erweiterung bräuchte eine eigene Kontextregel.
- `py` (Python-Launcher), `subprocess` mit `shell=True` und Skriptdateien, die erst zur Laufzeit gelesen werden, sieht der Hook nicht.
- Ein Befehl, der ein lokales `python3` und zugleich `ssh` enthält, bleibt still (Weiche gilt für den ganzen Befehl).
- `cmd` zählt nur mit `/c` oder `//c` direkt hinter dem Namen; `cmd /d /c` oder `cmd /s /c` sind kein Windows-Kontext.
- Im Windows-Kontext zählt nur die erste Weiche einer Zeile: `powershell -c "wsl -- bash a; bash b"` bleibt still.
- Workflow-Subagenten laufen mit derselben `settings.json`; der Hook wirkt dort mit. Ob ihr Kontext den Hinweis zeigt, belegt erst ein Lauf.
- Dieser Hook ist ein Fangnetz, kein Nachweis. Er erkennt Muster im Befehlstext, nicht, was der Befehl tut.
## Referenzen
- [[AI/Regelwerk/pruefwerkzeuge|↑ Prüfwerkzeuge]]
- [[AI/Regelwerk/windows-shell|windows-shell.md]]