No-Progress-Bremse: Schauen ist keine Schleife + Wiederaufnahme in alle SOULs
‼️ Die Bremse hat den Schaden angerichtet, den sie verhindern soll. Sie signiert den ERGEBNISTEXT von terminal-Aufrufen; die Bestandsaufnahme in Schritt 0 besteht aber aus vielen kurzen Schau-Befehlen (ls, cat, git log), deren Ausgaben sich stark aehneln. Nach dreien blockte sie den naechsten Blick — ausgerechnet `ls /tmp/konzept-*`. Der Worker las die Block-Meldung als "Verzeichnis existiert nicht", schloss daraus, das fertige Konzept sei nicht verifizierbar, und warf eine halbe Stunde Arbeit weg (Karte t_d26c3203, Log: "kein /tmp/konzept-* Verzeichnis gefunden (wegen No-Progress-Bremse)"). Die Bremse verlangt in ihrem eigenen Text "Diagnose statt Variation" — und verhinderte genau die. - _nur_lesend(): rein lesende Befehle (ls/cat/head/find/grep/git status|log|diff| ls-remote …, keine Umleitung) werden weder gezaehlt noch geblockt. Strukturell nach Befehls-ART, nicht per Fehlertext-Liste — die Bremse bleibt generisch. - Block-Meldung sagt jetzt ausdruecklich: "Dein Befehl wurde NICHT ausgefuehrt, das ist eine Bremse, KEIN Ergebnis — schliesse daraus nichts ueber Existenz oder Zustand." Ohne diesen Satz liest ein Agent den Block als Befund. - Schritt 0 (Wiederaufnahme) + FORTSCHRITT.md jetzt auch in werkstatt-SOUL (Klon/Branch pruefen: liegt der Branch schon auf Gitea -> verifizieren und abschliessen statt neu bauen) und betrieb-SOUL (vorhandene Messwerte NICHT neu messen — ein wiederholter Bench laedt 70-GB-Modelle und gefaehrdet Lucys Warm-Set). - projektstart: FORTSCHRITT.md gehoert ins Workspace-Wurzelverzeichnis, nicht in den Repo-Klon. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -43,6 +43,10 @@ STATE_TTL = 48 * 3600
|
||||
BLOCK_REASON = (
|
||||
"NO-PROGRESS-BREMSE: '{tool}' hat {n}x in Folge dasselbe Ergebnismuster geliefert — "
|
||||
"das ist Stillstand, egal wie sehr die Befehle variieren. STOPP. "
|
||||
"WICHTIG: Dein Befehl wurde NICHT ausgefuehrt. Das hier ist eine Bremse, KEIN Ergebnis — "
|
||||
"schliesse daraus NICHTS ueber die Existenz oder den Zustand von Dateien, Verzeichnissen "
|
||||
"oder Diensten (Vorfall 21.07.2026: ein Worker hielt diese Meldung fuer 'Verzeichnis nicht "
|
||||
"vorhanden' und baute eine halbe Stunde Arbeit neu). "
|
||||
"1) Benenne das Hindernis in EINEM Satz (was genau meldet das Ergebnis?). "
|
||||
"2) Diagnose statt Variation — bei SSH/Zugriff ZUERST: Schluessel-Passphrase pruefen "
|
||||
"(`ssh-keygen -y -f <key> </dev/null` — stilles 'Permission denied' = verschluesselter Key), "
|
||||
@@ -51,6 +55,44 @@ BLOCK_REASON = (
|
||||
"Commander uebergeben. Dein naechster Versuch ist frei — nutze ihn erst NACH der Diagnose."
|
||||
)
|
||||
|
||||
# Rein LESENDE Befehle nie bremsen (21.07.2026). Die Bremse verlangt selbst „Diagnose
|
||||
# statt Variation" — genau die besteht aus vielen kurzen Schau-Befehlen (ls/cat/git log),
|
||||
# deren Ergebnisse sich stark aehneln. Die Signatur hielt das fuer Stillstand und blockte
|
||||
# den naechsten Blick; der Worker las die Block-Meldung als „da ist nichts" und baute
|
||||
# alles neu (Karte t_d26c3203, eine halbe Stunde Arbeit weggeworfen). Geschaut wird also
|
||||
# ungebremst — gebremst wird nur, wer immer wieder dasselbe TUT.
|
||||
# Bewusst strukturell (Befehls-Art), nicht per Fehlertext-Liste: die Bremse soll generisch
|
||||
# bleiben und Neues selbst erkennen.
|
||||
_LESEND = {"ls", "cat", "head", "tail", "wc", "stat", "find", "grep", "rg", "file",
|
||||
"du", "df", "echo", "pwd", "tree", "readlink", "basename", "dirname", "which"}
|
||||
_GIT_LESEND = {"status", "log", "show", "diff", "ls-remote", "ls-files", "rev-parse",
|
||||
"merge-base", "describe"}
|
||||
|
||||
|
||||
def _nur_lesend(cmd: str) -> bool:
|
||||
"""True, wenn der Befehl ausschliesslich schaut — kein Schreiben, kein Eingriff."""
|
||||
cmd = (cmd or "").strip()
|
||||
if not cmd or ">" in cmd: # jede Umleitung = schreiben
|
||||
return False
|
||||
for teil in re.split(r"&&|\|\||;|\|", cmd):
|
||||
worte = teil.split()
|
||||
i = 0
|
||||
while i < len(worte) and "=" in worte[i] and not worte[i].startswith("-"):
|
||||
i += 1 # VAR=wert-Praefixe ueberspringen
|
||||
if i >= len(worte):
|
||||
return False
|
||||
verb = os.path.basename(worte[i])
|
||||
if verb == "git":
|
||||
rest = [w for w in worte[i + 1:] if not w.startswith("-")]
|
||||
# `git log …` oder `git -C <pfad> log …` → erstes oder zweites Wort zaehlt
|
||||
if not (rest[:1] and rest[0] in _GIT_LESEND) and \
|
||||
not (rest[1:2] and rest[1] in _GIT_LESEND):
|
||||
return False
|
||||
elif verb not in _LESEND:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
_NUM_RE = re.compile(r"\d+")
|
||||
_HEX_RE = re.compile(r"\b[0-9a-f]{8,}\b")
|
||||
_WS_RE = re.compile(r"\s+")
|
||||
@@ -113,6 +155,10 @@ def main() -> None:
|
||||
if tool == "terminal" and ("worker.sh" in str(_cmd) or "fremdblick.sh" in str(_cmd)):
|
||||
print("{}")
|
||||
return
|
||||
# Schauen ist keine Schleife (siehe _nur_lesend): weder zaehlen noch blocken.
|
||||
if tool == "terminal" and _nur_lesend(str(_cmd)):
|
||||
print("{}")
|
||||
return
|
||||
os.makedirs(STATE_DIR, exist_ok=True)
|
||||
sfile = os.path.join(STATE_DIR, _session_key(payload) + ".json")
|
||||
state = _load(sfile)
|
||||
|
||||
Reference in New Issue
Block a user