Erledigt (2026-09-26). Umgesetzt und veröffentlicht: 63f566f (Code, Tests, AGENTS.md, tools/CONTRACT.md, Version) und 16c911f (Prosa-Nachzug in README.md). Stand im laufenden Kandidaten: 7.1.0-beta.22. Folgebefunde: #147, #148, Nachtrag in #146.
Problem (Ausgangslage)
Den Fehlervertrag eines Kommandos (Ursache → Reaktion) braucht ein Agent genau dann, wenn das Kommando scheitert. Bis zu diesem Paket gab _util.fail() nur eine ERROR-Zeile aus, auf stdout über die Rich-console. Die Reaktion stand im Abschnitt ON FAILURE von wikitool <cmd> -h, also nur über einen zweiten Aufruf erreichbar. Genau dieses Nachschlagen wird in der Hitze eines Fehlschlags am ehesten übersprungen.
Exit 42 war nicht betroffen: Die Gates drucken ihre Wiederholungszeile selbst.
Ergebnis
Endet ein Aufruf über _util.fail() mit Exit 1, gibt er die Ausgabe in dieser Form aus:
Hat der Datensatz keine Exit-1-Ursache mit Reaktion, erscheint nur see: wikitool <path> -h. Ohne Click-Kontext, ohne Datensatz oder bei einem Fehler beim Rendern erscheint kein Hinweis, und das Verhalten ist dasselbe wie vorher.
Entscheidungen
D1 – c: ON FAILURE inline. Der Hinweis zeigt die Failures des laufenden Kommandos mit code == 1 und nicht leerer reaction, jeweils in der Form von -h. Das ging erst, seit #142 je Ursache einen eigenen Failure-Eintrag eingeführt hat.
Verworfen a (nur Verweis): Das Nachschlagen, um das es in diesem Paket geht, bliebe bestehen.
Verworfen b (ursachengenau): Alle 231 fail()-Aufrufe in 26 Dateien hätten einer Ursache zugeordnet werden müssen, dazu ein neuer Schlüssel an Failure, der driften kann, und eine eigene docs verify-Prüfung. b bleibt als Ausbau möglich, falls Messung zeigt, dass Agenten die Ursache falsch zuordnen oder abgelehnte Aufrufe unverändert wiederholen (Trajektorien-Regel „refused call repeated unchanged“, siehe #52).
Umfang, gemessen über alle 61 Datensätze: Median 2 Zeilen / 242 Zeichen, Maximum 9 Zeilen (dist upgrade) bzw. 1811 Zeichen (raw accept). Es wird nicht gekürzt.
D2 – stderr, Klartext. Der Hinweis wird mit sys.stderr.write geschrieben, nicht über Rich: Reaktionstexte enthalten [--flag], und Rich würde das als Markup verschlucken. Die ERROR-Zeile bleibt unverändert auf stdout.
D3 – Rückfall. Ein Datensatz ohne Exit-1-Ursache bekommt die see:-Zeile; heute betrifft das nur docs contract, siehe #146. Ohne Click-Kontext gibt es keinen Hinweis; das betrifft die Budget-Gate- und Loop-Breaker-Verweigerung in cli.main(), deren Traceback ist #147.
Wie gebaut
B1 – cli_contract.py:
path_of(ctx) ist öffentlich und ersetzt das bisherige cli._contract_path; cli.py ruft es jetzt dort auf.
render_failure_hint(rec) ist neu. render_on_failure_lines blieb unverändert, weil -h und die Markdown-Region weiterhin alle Codes zeigen; der Filter auf Code 1 steht in der neuen Funktion.
Den Kontext holt typer._click.globals.get_current_context(silent=True), dieselbe private Modulquelle wie beim Hilfe-Patch in cli.py.
Import, Lookup und Rendern stehen in try/except Exception.
B3 – Tests (13 neu, volle Suite 1535):
test_cli_contract.py: Filter auf Code 1 mit Reaktion, see:-Rückfall, path_of.
test_util.py: Hinweis nur auf stderr bei unverändertem stdout, Rückfall, kein Kontext, kein Datensatz, Renderfehler wird geschluckt.
test_cli.py: echte Kommandos touch und xref add über die Kommando-Fixture; ein Subprozess mit gemergten Streams (docs contract gegen ein leeres CHEMENU_ROOT) für Reihenfolge und Rückfall; Refund über _run_traced.
Das befürchtete Risiko trat nicht ein: Keine bestehende CliRunner-Assertion vergleicht result.output exakt.
B4 – Doku:
AGENTS.md § Tool error contract, Fall 2.
tools/CONTRACT.md § Usage, ohne Issue-Nummer, weil die Datei ausgeliefert wird.
Docstrings von Failure und fail().
README.md (Nachzug in stack-close).
tools/README.md beschreibt die Fehlerausgabe nicht und blieb unverändert.
B5 – Version:version bump --minor --impact medium → 7.1.0-beta.22, mit Changeset-Eintrag in CHANGES.md.
Invarianten
Exit-Codes ändern sich nicht, auch nicht bei einem Renderfehler oder ohne Kontext (test_fail_swallows_a_hint_rendering_failure, test_fail_without_a_click_context_prints_no_hint).
stdout bleibt byte-gleich; der Hinweis steht nur auf stderr.
Unter 2>&1 steht die ERROR-Zeile zuerst (Subprozess-Test).
Akzeptanzkriterien
Jeder Aufruf, der innerhalb eines Kommandos über _util.fail() mit Exit 1 endet, gibt nach der ERROR-Zeile den Hinweis bzw. die see:-Zeile aus. Belegt über ein Fixture-Kommando und drei echte Kommandos (touch, xref add, docs contract).
Einträge mit code 0 oder 42 und Einträge ohne reaction erscheinen nicht im Hinweis (test_render_failure_hint_shows_only_exit_1_causes_with_a_reaction, dazu test_fail_prints_the_hint_on_stderr_leaving_stdout_untouched).
stdout ist im Fehlerfall byte-gleich; der Hinweis steht nur auf stderr (test_util.py prüft stdout exakt).
Unter 2>&1 steht die ERROR-Zeile vor dem Hinweis (test_stderr_hint_follows_the_error_line_when_streams_are_merged).
Der Exit-Code bleibt 1 bei einem Renderfehler und ohne Click-Kontext (Tests oben).
Der Budget-Refund nach fail() ist unverändert (Test oben).
cli.py hat keine eigene Pfadauflösung mehr und nutzt cli_contract.path_of.
AGENTS.md § Tool error contract und tools/CONTRACT.md § Usage beschreiben den Hinweis. docs verify, instructions verify und die volle pytest-Suite (1535) waren lokal grün. CI war für 63f566f grün (Läufe 403 und 404) und ebenso für 16c911f (siehe Abschlusskommentar).
Außerhalb dieses Pakets
#147 – Die Budget-Gate- und Loop-Breaker-Verweigerung druckt nach der ERROR-Zeile einen Python-Traceback, und ihre Meldungen verweisen auf Abschnitte, die es nicht gibt.
#148 – cli.py setzt den Hilfe-Patch ein zweites Mal außerhalb des try und hebt damit den dokumentierten Rückfall auf.
#146 (Nachtrag) – Der Datensatz von docs contract nennt keine Exit-1-Ursache, obwohl der Code eine kennt.
instructions/gates.md sagt in der Exit-Tabelle weiter „Read the ERROR line“. Das ist nicht falsch, weil die Regel in AGENTS.md steht; die Zeile wurde deshalb bewusst nicht angefasst.
Ablauf
Entwurf, D1-Entscheidung mit dem Betreiber und Bauplan: Claude Opus 5.5.
Umsetzung (Code, Tests, Doku, Version, Publish): Claude Sonnet 5.
Abschluss (README-Nachzug, Body, Schließen): Claude Opus 5.5.
Der Publish von 63f566f lief bei genau 10 Dateien ins Mass-Update Gate und ging nach Freigabe durch den Betreiber durch.
**Erledigt (2026-09-26).** Umgesetzt und veröffentlicht: `63f566f` (Code, Tests, AGENTS.md, `tools/CONTRACT.md`, Version) und `16c911f` (Prosa-Nachzug in README.md). Stand im laufenden Kandidaten: 7.1.0-beta.22. Folgebefunde: #147, #148, Nachtrag in #146.
## Problem (Ausgangslage)
Den Fehlervertrag eines Kommandos (Ursache → Reaktion) braucht ein Agent genau dann, wenn das Kommando scheitert. Bis zu diesem Paket gab `_util.fail()` nur eine `ERROR`-Zeile aus, auf stdout über die Rich-`console`. Die Reaktion stand im Abschnitt ON FAILURE von `wikitool <cmd> -h`, also nur über einen zweiten Aufruf erreichbar. Genau dieses Nachschlagen wird in der Hitze eines Fehlschlags am ehesten übersprungen.
Exit 42 war nicht betroffen: Die Gates drucken ihre Wiederholungszeile selbst.
## Ergebnis
Endet ein Aufruf über `_util.fail()` mit Exit 1, gibt er die Ausgabe in dieser Form aus:
```
ERROR <msg> ← stdout, byte-gleich wie vorher
ON FAILURE (wikitool <path> -h): ← stderr, Klartext
<cause> -> <reaction>
<label>: <cause> -> <reaction>
```
Hat der Datensatz keine Exit-1-Ursache mit Reaktion, erscheint nur `see: wikitool <path> -h`. Ohne Click-Kontext, ohne Datensatz oder bei einem Fehler beim Rendern erscheint kein Hinweis, und das Verhalten ist dasselbe wie vorher.
## Entscheidungen
- **D1 – c: ON FAILURE inline.** Der Hinweis zeigt die `Failure`s des laufenden Kommandos mit `code == 1` und nicht leerer `reaction`, jeweils in der Form von `-h`. Das ging erst, seit #142 je Ursache einen eigenen `Failure`-Eintrag eingeführt hat.
- Verworfen **a (nur Verweis)**: Das Nachschlagen, um das es in diesem Paket geht, bliebe bestehen.
- Verworfen **b (ursachengenau)**: Alle 231 `fail()`-Aufrufe in 26 Dateien hätten einer Ursache zugeordnet werden müssen, dazu ein neuer Schlüssel an `Failure`, der driften kann, und eine eigene `docs verify`-Prüfung. **b** bleibt als Ausbau möglich, falls Messung zeigt, dass Agenten die Ursache falsch zuordnen oder abgelehnte Aufrufe unverändert wiederholen (Trajektorien-Regel „refused call repeated unchanged“, siehe #52).
- Umfang, gemessen über alle 61 Datensätze: Median 2 Zeilen / 242 Zeichen, Maximum 9 Zeilen (`dist upgrade`) bzw. 1811 Zeichen (`raw accept`). Es wird nicht gekürzt.
- **D2 – stderr, Klartext.** Der Hinweis wird mit `sys.stderr.write` geschrieben, nicht über Rich: Reaktionstexte enthalten `[--flag]`, und Rich würde das als Markup verschlucken. Die `ERROR`-Zeile bleibt unverändert auf stdout.
- **D3 – Rückfall.** Ein Datensatz ohne Exit-1-Ursache bekommt die `see:`-Zeile; heute betrifft das nur `docs contract`, siehe #146. Ohne Click-Kontext gibt es keinen Hinweis; das betrifft die Budget-Gate- und Loop-Breaker-Verweigerung in `cli.main()`, deren Traceback ist #147.
## Wie gebaut
- **B1 – `cli_contract.py`:**
- `path_of(ctx)` ist öffentlich und ersetzt das bisherige `cli._contract_path`; `cli.py` ruft es jetzt dort auf.
- `render_failure_hint(rec)` ist neu. `render_on_failure_lines` blieb unverändert, weil `-h` und die Markdown-Region weiterhin alle Codes zeigen; der Filter auf Code 1 steht in der neuen Funktion.
- **B2 – `_util.fail()`:**
- Reihenfolge: `_declined = True` → `ERROR` → `console.file.flush()` → Hinweis auf stderr → `typer.Exit(1)`.
- Den Kontext holt `typer._click.globals.get_current_context(silent=True)`, dieselbe private Modulquelle wie beim Hilfe-Patch in `cli.py`.
- Import, Lookup und Rendern stehen in `try/except Exception`.
- **B3 – Tests** (13 neu, volle Suite 1535):
- `test_cli_contract.py`: Filter auf Code 1 mit Reaktion, `see:`-Rückfall, `path_of`.
- `test_util.py`: Hinweis nur auf stderr bei unverändertem stdout, Rückfall, kein Kontext, kein Datensatz, Renderfehler wird geschluckt.
- `test_cli.py`: echte Kommandos `touch` und `xref add` über die Kommando-Fixture; ein Subprozess mit gemergten Streams (`docs contract` gegen ein leeres `CHEMENU_ROOT`) für Reihenfolge und Rückfall; Refund über `_run_traced`.
- Das befürchtete Risiko trat nicht ein: Keine bestehende `CliRunner`-Assertion vergleicht `result.output` exakt.
- **B4 – Doku:**
- AGENTS.md § Tool error contract, Fall 2.
- `tools/CONTRACT.md` § Usage, ohne Issue-Nummer, weil die Datei ausgeliefert wird.
- Docstrings von `Failure` und `fail()`.
- README.md (Nachzug in `stack-close`).
- `tools/README.md` beschreibt die Fehlerausgabe nicht und blieb unverändert.
- **B5 – Version:** `version bump --minor --impact medium` → 7.1.0-beta.22, mit Changeset-Eintrag in `CHANGES.md`.
## Invarianten
- [x] Exit-Codes ändern sich nicht, auch nicht bei einem Renderfehler oder ohne Kontext (`test_fail_swallows_a_hint_rendering_failure`, `test_fail_without_a_click_context_prints_no_hint`).
- [x] Budget-Refund unverändert (`test_declined_call_is_still_refunded_after_the_new_stderr_hint`).
- [x] stdout bleibt byte-gleich; der Hinweis steht nur auf stderr.
- [x] Unter `2>&1` steht die `ERROR`-Zeile zuerst (Subprozess-Test).
## Akzeptanzkriterien
- [x] Jeder Aufruf, der innerhalb eines Kommandos über `_util.fail()` mit Exit 1 endet, gibt nach der `ERROR`-Zeile den Hinweis bzw. die `see:`-Zeile aus. Belegt über ein Fixture-Kommando und drei echte Kommandos (`touch`, `xref add`, `docs contract`).
- [x] Einträge mit `code` 0 oder 42 und Einträge ohne `reaction` erscheinen nicht im Hinweis (`test_render_failure_hint_shows_only_exit_1_causes_with_a_reaction`, dazu `test_fail_prints_the_hint_on_stderr_leaving_stdout_untouched`).
- [x] stdout ist im Fehlerfall byte-gleich; der Hinweis steht nur auf stderr (`test_util.py` prüft stdout exakt).
- [x] Unter `2>&1` steht die `ERROR`-Zeile vor dem Hinweis (`test_stderr_hint_follows_the_error_line_when_streams_are_merged`).
- [x] Der Exit-Code bleibt 1 bei einem Renderfehler und ohne Click-Kontext (Tests oben).
- [x] Der Budget-Refund nach `fail()` ist unverändert (Test oben).
- [x] `cli.py` hat keine eigene Pfadauflösung mehr und nutzt `cli_contract.path_of`.
- [x] AGENTS.md § Tool error contract und `tools/CONTRACT.md` § Usage beschreiben den Hinweis. `docs verify`, `instructions verify` und die volle `pytest`-Suite (1535) waren lokal grün. CI war für `63f566f` grün (Läufe 403 und 404) und ebenso für `16c911f` (siehe Abschlusskommentar).
## Außerhalb dieses Pakets
- #147 – Die Budget-Gate- und Loop-Breaker-Verweigerung druckt nach der `ERROR`-Zeile einen Python-Traceback, und ihre Meldungen verweisen auf Abschnitte, die es nicht gibt.
- #148 – `cli.py` setzt den Hilfe-Patch ein zweites Mal außerhalb des `try` und hebt damit den dokumentierten Rückfall auf.
- #146 (Nachtrag) – Der Datensatz von `docs contract` nennt keine Exit-1-Ursache, obwohl der Code eine kennt.
- `instructions/gates.md` sagt in der Exit-Tabelle weiter „Read the `ERROR` line“. Das ist nicht falsch, weil die Regel in AGENTS.md steht; die Zeile wurde deshalb bewusst nicht angefasst.
## Ablauf
- Entwurf, D1-Entscheidung mit dem Betreiber und Bauplan: Claude Opus 5.5.
- Umsetzung (Code, Tests, Doku, Version, Publish): Claude Sonnet 5.
- Abschluss (README-Nachzug, Body, Schließen): Claude Opus 5.5.
- Der Publish von `63f566f` lief bei genau 10 Dateien ins Mass-Update Gate und ging nach Freigabe durch den Betreiber durch.
Blocker entfallen (#121, #142 geschlossen): status/blocked ist entfernt, kind/decision wurde zu kind/build.
D1 ist entschieden, und zwar für die neue Variante c, nicht für den bisherigen Vorschlag a: fail() druckt die Exit-1-Zeilen aus ON FAILURE inline. Das ist erst seit #142 möglich (ein Failure je Ursache). a und b sind mit Begründung verworfen.
D2 ist entschieden: stderr, als Klartext ohne Rich. Neu ist D3 (Rückfall).
Neu: Ausgabeform, Bauplan B1–B5 und endgültige Akzeptanzkriterien.
Nebenbefunde ausgelagert: #147 (Traceback bei Gate-Verweigerung), #148 (Hilfe-Patch außerhalb von try) und ein Nachtrag in #146 (docs contract).
**Changelog:**
- Blocker entfallen (#121, #142 geschlossen): `status/blocked` ist entfernt, `kind/decision` wurde zu `kind/build`.
- D1 ist entschieden, und zwar für die neue Variante **c**, nicht für den bisherigen Vorschlag **a**: `fail()` druckt die Exit-1-Zeilen aus ON FAILURE inline. Das ist erst seit #142 möglich (ein `Failure` je Ursache). **a** und **b** sind mit Begründung verworfen.
- D2 ist entschieden: stderr, als Klartext ohne Rich. Neu ist D3 (Rückfall).
- Neu: Ausgabeform, Bauplan B1–B5 und endgültige Akzeptanzkriterien.
- Nebenbefunde ausgelagert: #147 (Traceback bei Gate-Verweigerung), #148 (Hilfe-Patch außerhalb von `try`) und ein Nachtrag in #146 (`docs contract`).
Changelog: Body auf den Endstand umgeschrieben: Bauplan → „Wie gebaut“, alle Invarianten und Akzeptanzkriterien abgehakt, die Testnamen als Belege genannt, Modellwahl je Phase unter „Ablauf“. Neu ist der README-Nachzug 16c911f. CI war grün für 63f566f (Läufe 403, 404) und 16c911f (Lauf 405). Geschlossen.
**Changelog:** Body auf den Endstand umgeschrieben: Bauplan → „Wie gebaut“, alle Invarianten und Akzeptanzkriterien abgehakt, die Testnamen als Belege genannt, Modellwahl je Phase unter „Ablauf“. Neu ist der README-Nachzug `16c911f`. CI war grün für `63f566f` (Läufe 403, 404) und `16c911f` (Lauf 405). Geschlossen.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Erledigt (2026-09-26). Umgesetzt und veröffentlicht:
63f566f(Code, Tests, AGENTS.md,tools/CONTRACT.md, Version) und16c911f(Prosa-Nachzug in README.md). Stand im laufenden Kandidaten: 7.1.0-beta.22. Folgebefunde: #147, #148, Nachtrag in #146.Problem (Ausgangslage)
Den Fehlervertrag eines Kommandos (Ursache → Reaktion) braucht ein Agent genau dann, wenn das Kommando scheitert. Bis zu diesem Paket gab
_util.fail()nur eineERROR-Zeile aus, auf stdout über die Rich-console. Die Reaktion stand im Abschnitt ON FAILURE vonwikitool <cmd> -h, also nur über einen zweiten Aufruf erreichbar. Genau dieses Nachschlagen wird in der Hitze eines Fehlschlags am ehesten übersprungen.Exit 42 war nicht betroffen: Die Gates drucken ihre Wiederholungszeile selbst.
Ergebnis
Endet ein Aufruf über
_util.fail()mit Exit 1, gibt er die Ausgabe in dieser Form aus:Hat der Datensatz keine Exit-1-Ursache mit Reaktion, erscheint nur
see: wikitool <path> -h. Ohne Click-Kontext, ohne Datensatz oder bei einem Fehler beim Rendern erscheint kein Hinweis, und das Verhalten ist dasselbe wie vorher.Entscheidungen
Failures des laufenden Kommandos mitcode == 1und nicht leererreaction, jeweils in der Form von-h. Das ging erst, seit #142 je Ursache einen eigenenFailure-Eintrag eingeführt hat.fail()-Aufrufe in 26 Dateien hätten einer Ursache zugeordnet werden müssen, dazu ein neuer Schlüssel anFailure, der driften kann, und eine eigenedocs verify-Prüfung. b bleibt als Ausbau möglich, falls Messung zeigt, dass Agenten die Ursache falsch zuordnen oder abgelehnte Aufrufe unverändert wiederholen (Trajektorien-Regel „refused call repeated unchanged“, siehe #52).dist upgrade) bzw. 1811 Zeichen (raw accept). Es wird nicht gekürzt.sys.stderr.writegeschrieben, nicht über Rich: Reaktionstexte enthalten[--flag], und Rich würde das als Markup verschlucken. DieERROR-Zeile bleibt unverändert auf stdout.see:-Zeile; heute betrifft das nurdocs contract, siehe #146. Ohne Click-Kontext gibt es keinen Hinweis; das betrifft die Budget-Gate- und Loop-Breaker-Verweigerung incli.main(), deren Traceback ist #147.Wie gebaut
cli_contract.py:path_of(ctx)ist öffentlich und ersetzt das bisherigecli._contract_path;cli.pyruft es jetzt dort auf.render_failure_hint(rec)ist neu.render_on_failure_linesblieb unverändert, weil-hund die Markdown-Region weiterhin alle Codes zeigen; der Filter auf Code 1 steht in der neuen Funktion._util.fail():_declined = True→ERROR→console.file.flush()→ Hinweis auf stderr →typer.Exit(1).typer._click.globals.get_current_context(silent=True), dieselbe private Modulquelle wie beim Hilfe-Patch incli.py.try/except Exception.test_cli_contract.py: Filter auf Code 1 mit Reaktion,see:-Rückfall,path_of.test_util.py: Hinweis nur auf stderr bei unverändertem stdout, Rückfall, kein Kontext, kein Datensatz, Renderfehler wird geschluckt.test_cli.py: echte Kommandostouchundxref addüber die Kommando-Fixture; ein Subprozess mit gemergten Streams (docs contractgegen ein leeresCHEMENU_ROOT) für Reihenfolge und Rückfall; Refund über_run_traced.CliRunner-Assertion vergleichtresult.outputexakt.tools/CONTRACT.md§ Usage, ohne Issue-Nummer, weil die Datei ausgeliefert wird.Failureundfail().stack-close).tools/README.mdbeschreibt die Fehlerausgabe nicht und blieb unverändert.version bump --minor --impact medium→ 7.1.0-beta.22, mit Changeset-Eintrag inCHANGES.md.Invarianten
test_fail_swallows_a_hint_rendering_failure,test_fail_without_a_click_context_prints_no_hint).test_declined_call_is_still_refunded_after_the_new_stderr_hint).2>&1steht dieERROR-Zeile zuerst (Subprozess-Test).Akzeptanzkriterien
_util.fail()mit Exit 1 endet, gibt nach derERROR-Zeile den Hinweis bzw. diesee:-Zeile aus. Belegt über ein Fixture-Kommando und drei echte Kommandos (touch,xref add,docs contract).code0 oder 42 und Einträge ohnereactionerscheinen nicht im Hinweis (test_render_failure_hint_shows_only_exit_1_causes_with_a_reaction, dazutest_fail_prints_the_hint_on_stderr_leaving_stdout_untouched).test_util.pyprüft stdout exakt).2>&1steht dieERROR-Zeile vor dem Hinweis (test_stderr_hint_follows_the_error_line_when_streams_are_merged).fail()ist unverändert (Test oben).cli.pyhat keine eigene Pfadauflösung mehr und nutztcli_contract.path_of.tools/CONTRACT.md§ Usage beschreiben den Hinweis.docs verify,instructions verifyund die vollepytest-Suite (1535) waren lokal grün. CI war für63f566fgrün (Läufe 403 und 404) und ebenso für16c911f(siehe Abschlusskommentar).Außerhalb dieses Pakets
ERROR-Zeile einen Python-Traceback, und ihre Meldungen verweisen auf Abschnitte, die es nicht gibt.cli.pysetzt den Hilfe-Patch ein zweites Mal außerhalb destryund hebt damit den dokumentierten Rückfall auf.docs contractnennt keine Exit-1-Ursache, obwohl der Code eine kennt.instructions/gates.mdsagt in der Exit-Tabelle weiter „Read theERRORline“. Das ist nicht falsch, weil die Regel in AGENTS.md steht; die Zeile wurde deshalb bewusst nicht angefasst.Ablauf
63f566flief bei genau 10 Dateien ins Mass-Update Gate und ging nach Freigabe durch den Betreiber durch.Changelog:
status/blockedist entfernt,kind/decisionwurde zukind/build.fail()druckt die Exit-1-Zeilen aus ON FAILURE inline. Das ist erst seit #142 möglich (einFailureje Ursache). a und b sind mit Begründung verworfen.try) und ein Nachtrag in #146 (docs contract).Changelog: Body auf den Endstand umgeschrieben: Bauplan → „Wie gebaut“, alle Invarianten und Akzeptanzkriterien abgehakt, die Testnamen als Belege genannt, Modellwahl je Phase unter „Ablauf“. Neu ist der README-Nachzug
16c911f. CI war grün für63f566f(Läufe 403, 404) und16c911f(Lauf 405). Geschlossen.