publish hängt „Files changed:“ hinter die Trailer der Message – git erkennt Co-Authored-By: nicht mehr #149

Closed
opened 2026-09-26 16:58:31 +00:00 by torben · 2 comments
Owner

Befund (behoben in 8.0.0-beta.23, 80488be)

publish baute die Commit-Message als f"{message}\n\nFiles changed:\n{file_list}" (tools/chemenu/commands/git_publish.py, publish_command). Endete --message mit einem Trailer-Block – etwa Co-Authored-By: … / Claude-Session: …, wie ihn eine Agent-Session anhängt –, stand die Dateiliste danach. Git liest Trailer nur im letzten Absatz der Message, und das war „Files changed:“ samt Liste.

Belegt an 8f61209 (Abschluss von #146) und c77bda2 (#154): git log -1 --format='%(trailers)' und git interpret-trailers --parse waren leer, obwohl die Message beide Zeilen trug. Keiner der 15 Commits vor dem Fix hatte einen lesbaren Co-Authored-By-Trailer. Damit fehlte die Mitautorschaft überall, wo Trailer ausgewertet werden (Gitea- und GitHub-Anzeige, git shortlog --group=trailer:co-authored-by), und zwar bei jedem Publish mit Attribution.

Umsetzung

Keine eigene Trailer-Regex. Die neue Funktion commit_message(message, changed_files) in git_publish.py lässt git urteilen:

  1. git interpret-trailers --parse --no-divider auf --message. Leer → die bisherige Message, byte-identisch.
  2. Sonst wird die Message am letzten Leerzeilen-Absatz geteilt, und der Kandidat ist Kopf + "Files changed:"-Absatz + letzter Absatz.
  3. Der Kandidat gilt nur, wenn interpret-trailers auf ihm dieselben Trailer liest wie auf --message, sonst bleibt die bisherige Message. Damit entscheidet git über jeden Randfall: Fortsetzungszeilen, (cherry picked from …), die 25-%-Regel, die Titelzeile, Kommentarzeilen.

--no-divider, weil git log --format=%(trailers) eine ----Zeile nicht als Ende der Message liest; geprüft mit git 2.54. interpret-trailers läuft in config.ROOT und sieht dieselbe trailer.*-Konfiguration wie git log. _run nimmt dafür ein optionales input= (stdin).

Gate-Tokens unberührt: changeset_token hasht Pfade, Blob-Digests, Threshold, Remote, Branch und --path, rebase_review_token Remote, Branch, die beiden SHAs und die Overlap-Liste. --message geht in keinen der beiden ein.

Akzeptanzkriterien

  • Nach publish --message "<Betreff>\n\n<Text>\n\nCo-Authored-By: A <a@x>\nClaude-Session: https://…" liefert git log -1 --format='%(trailers:key=Co-Authored-By,valueonly)' genau A <a@x>, und die Message enthält „Files changed:“ samt vollständiger Dateiliste – test_publish_commits_trailers_git_log_can_read. Am echten Repo bestätigt: 80488be selbst ist mit Attribution publiziert, und %(trailers:key=Co-Authored-By,valueonly) liefert Claude Opus 5.5 <noreply@anthropic.com>.
  • Ohne Trailer-Block ist die Message byte-identisch zur bisherigen – test_a_message_without_a_trailer_block_is_byte_identical_to_before (fünf Fälle) und test_publish_without_trailers_commits_the_same_message_as_before (echter Commit).
  • Ein Absatz, der nur aussieht wie ein Trailer, wird nicht verschoben. Geprüft sind ein Prosa-Absatz mit Doppelpunkt, ein Trailer als Titelzeile und Trailer, auf die noch ein Absatz folgt. In allen drei Fällen ist interpret-trailers leer, und die Message bleibt unverändert. Die Gegenseite (Fortsetzungszeile, (cherry picked from …) + Signed-off-by neben Freitext, --- im Text, Leerraum am Ende) prüft test_git_reads_the_same_trailers_after_the_file_list_is_added.
  • Die Umstellung ändert nichts an den Gate-Tokens: --message geht in keinen Token ein. test_a_mass_update_token_does_not_depend_on_the_message zeigt das. Ein Token aus einer Verweigerung mit schlichter Message gibt dasselbe Changeset mit Trailer-Block frei, und die Trailer bleiben lesbar.
  • Der publish-Datensatz nennt in NOTES, wo die Dateiliste steht, dass ein abschließender Trailer-Block ihr folgt und dass --message in keinen Token eingeht. tools/CONTRACT.md ist per docs contract --apply regeneriert.
  • docs verify, instructions verify und pytest lokal grün (2057 passed, 3 skipped). CI-Run 497 grün (verify und pwsh), Release-Run 498 grün. Version-Bump --patch auf 8.0.0-beta.23 mit CHANGES.md-Abschnitt.

Nicht im Umfang

  • Die schon ausgelieferten Commits (8f61209, c77bda2 und alle bis c65d559) bleiben, wie sie sind – ein Umschreiben der Historie bräuchte einen Force-Push, und den schließt Invariante 5 aus.
  • Ob publish Attribution selbst anhängen sollte, statt sie aus --message zu übernehmen: nicht Teil dieses Befunds. Die Zeilen sind sitzungs- und harness-spezifisch und gehören zu dem, der die Message schreibt.
  • Kein docs/-Text, keine README, INSTALL.md und keine Instruction behauptet etwas über das Layout der Commit-Message (geprüft per grep). Außer dem publish-Datensatz war nichts nachzuziehen.
## Befund (behoben in 8.0.0-beta.23, `80488be`) `publish` baute die Commit-Message als `f"{message}\n\nFiles changed:\n{file_list}"` (`tools/chemenu/commands/git_publish.py`, `publish_command`). Endete `--message` mit einem Trailer-Block – etwa `Co-Authored-By: …` / `Claude-Session: …`, wie ihn eine Agent-Session anhängt –, stand die Dateiliste danach. Git liest Trailer nur im **letzten** Absatz der Message, und das war „Files changed:“ samt Liste. Belegt an `8f61209` (Abschluss von #146) und `c77bda2` (#154): `git log -1 --format='%(trailers)'` und `git interpret-trailers --parse` waren leer, obwohl die Message beide Zeilen trug. Keiner der 15 Commits vor dem Fix hatte einen lesbaren `Co-Authored-By`-Trailer. Damit fehlte die Mitautorschaft überall, wo Trailer ausgewertet werden (Gitea- und GitHub-Anzeige, `git shortlog --group=trailer:co-authored-by`), und zwar bei jedem Publish mit Attribution. ## Umsetzung Keine eigene Trailer-Regex. Die neue Funktion `commit_message(message, changed_files)` in `git_publish.py` lässt git urteilen: 1. `git interpret-trailers --parse --no-divider` auf `--message`. Leer → die bisherige Message, byte-identisch. 2. Sonst wird die Message am letzten Leerzeilen-Absatz geteilt, und der Kandidat ist `Kopf + "Files changed:"-Absatz + letzter Absatz`. 3. Der Kandidat gilt nur, wenn `interpret-trailers` auf ihm **dieselben** Trailer liest wie auf `--message`, sonst bleibt die bisherige Message. Damit entscheidet git über jeden Randfall: Fortsetzungszeilen, `(cherry picked from …)`, die 25-%-Regel, die Titelzeile, Kommentarzeilen. `--no-divider`, weil `git log --format=%(trailers)` eine `---`-Zeile nicht als Ende der Message liest; geprüft mit git 2.54. `interpret-trailers` läuft in `config.ROOT` und sieht dieselbe `trailer.*`-Konfiguration wie `git log`. `_run` nimmt dafür ein optionales `input=` (stdin). Gate-Tokens unberührt: `changeset_token` hasht Pfade, Blob-Digests, Threshold, Remote, Branch und `--path`, `rebase_review_token` Remote, Branch, die beiden SHAs und die Overlap-Liste. `--message` geht in keinen der beiden ein. ## Akzeptanzkriterien - [x] Nach `publish --message "<Betreff>\n\n<Text>\n\nCo-Authored-By: A <a@x>\nClaude-Session: https://…"` liefert `git log -1 --format='%(trailers:key=Co-Authored-By,valueonly)'` genau `A <a@x>`, und die Message enthält „Files changed:“ samt vollständiger Dateiliste – `test_publish_commits_trailers_git_log_can_read`. Am echten Repo bestätigt: `80488be` selbst ist mit Attribution publiziert, und `%(trailers:key=Co-Authored-By,valueonly)` liefert `Claude Opus 5.5 <noreply@anthropic.com>`. - [x] Ohne Trailer-Block ist die Message byte-identisch zur bisherigen – `test_a_message_without_a_trailer_block_is_byte_identical_to_before` (fünf Fälle) und `test_publish_without_trailers_commits_the_same_message_as_before` (echter Commit). - [x] Ein Absatz, der nur *aussieht* wie ein Trailer, wird nicht verschoben. Geprüft sind ein Prosa-Absatz mit Doppelpunkt, ein Trailer als Titelzeile und Trailer, auf die noch ein Absatz folgt. In allen drei Fällen ist `interpret-trailers` leer, und die Message bleibt unverändert. Die Gegenseite (Fortsetzungszeile, `(cherry picked from …)` + `Signed-off-by` neben Freitext, `---` im Text, Leerraum am Ende) prüft `test_git_reads_the_same_trailers_after_the_file_list_is_added`. - [x] Die Umstellung ändert nichts an den Gate-Tokens: `--message` geht in keinen Token ein. `test_a_mass_update_token_does_not_depend_on_the_message` zeigt das. Ein Token aus einer Verweigerung mit schlichter Message gibt dasselbe Changeset mit Trailer-Block frei, und die Trailer bleiben lesbar. - [x] Der `publish`-Datensatz nennt in NOTES, wo die Dateiliste steht, dass ein abschließender Trailer-Block ihr folgt und dass `--message` in keinen Token eingeht. `tools/CONTRACT.md` ist per `docs contract --apply` regeneriert. - [x] `docs verify`, `instructions verify` und `pytest` lokal grün (2057 passed, 3 skipped). CI-Run 497 grün (`verify` und `pwsh`), Release-Run 498 grün. Version-Bump `--patch` auf 8.0.0-beta.23 mit `CHANGES.md`-Abschnitt. ## Nicht im Umfang - Die schon ausgelieferten Commits (`8f61209`, `c77bda2` und alle bis `c65d559`) bleiben, wie sie sind – ein Umschreiben der Historie bräuchte einen Force-Push, und den schließt Invariante 5 aus. - Ob `publish` Attribution selbst anhängen sollte, statt sie aus `--message` zu übernehmen: nicht Teil dieses Befunds. Die Zeilen sind sitzungs- und harness-spezifisch und gehören zu dem, der die Message schreibt. - Kein `docs/`-Text, keine README, `INSTALL.md` und keine Instruction behauptet etwas über das Layout der Commit-Message (geprüft per grep). Außer dem `publish`-Datensatz war nichts nachzuziehen.
torben added the prio/plannedsize/Sarea/workflowkind/build labels 2026-09-26 16:58:31 +00:00
Author
Owner

Changelog (2026-10-02): Zweiter Beleg im Befund: c77bda2 (#154). %(trailers) und git interpret-trailers --parse sind leer, obwohl --message mit Co-Authored-By:/Claude-Session: endete. Keiner der letzten 15 Commits auf main hat einen lesbaren Trailer. Die Zeilenangabe zum Code ist auf Z. 1377 nachgezogen.

**Changelog (2026-10-02):** Zweiter Beleg im Befund: `c77bda2` (#154). `%(trailers)` und `git interpret-trailers --parse` sind leer, obwohl `--message` mit `Co-Authored-By:`/`Claude-Session:` endete. Keiner der letzten 15 Commits auf `main` hat einen lesbaren Trailer. Die Zeilenangabe zum Code ist auf Z. 1377 nachgezogen.
Author
Owner

Changelog (2026-10-02): Umgesetzt in 80488be (8.0.0-beta.23). Body auf Endstand: Befund in der Vergangenheit, der „Entwurf“ heißt jetzt „Umsetzung“, alle Kriterien sind mit ihren Tests abgehakt, CI-Run 497 und Release-Run 498 sind grün, und der Publish-Commit selbst trägt einen lesbaren Co-Authored-By. Geschlossen.

**Changelog (2026-10-02):** Umgesetzt in `80488be` (8.0.0-beta.23). Body auf Endstand: Befund in der Vergangenheit, der „Entwurf“ heißt jetzt „Umsetzung“, alle Kriterien sind mit ihren Tests abgehakt, CI-Run 497 und Release-Run 498 sind grün, und der Publish-Commit selbst trägt einen lesbaren `Co-Authored-By`. Geschlossen.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: torben/chemenu#149