From 0b0a42cfb2020c3de53b3b522c3b942a85d02b4c Mon Sep 17 00:00:00 2001 From: Waschtl904 Date: Thu, 10 Sep 2026 04:14:59 +0000 Subject: [PATCH 1/3] ci(integrity): make workflow race-tolerant - Rebase-and-retry up to three times on non-fast-forward push - Add concurrency group 'integrity-main' (no cancel-in-progress) so workflow_dispatch and push runs serialize on main - On persistent conflict, exit gracefully: the sibling run has authoritative INTEGRITY.md --- .github/workflows/integrity.yml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integrity.yml b/.github/workflows/integrity.yml index 6fe2e20e..7462e5ec 100644 --- a/.github/workflows/integrity.yml +++ b/.github/workflows/integrity.yml @@ -85,4 +85,25 @@ jobs: git config user.email "41898282+github-actions[bot]@users.noreply.github.com" git add INTEGRITY.md git commit -m "chore(integrity): refresh INTEGRITY.md hash tree" - git push + # Robust against concurrent runs: rebase-and-retry, then bail + # gracefully if a sibling run already pushed a newer hash tree. + for attempt in 1 2 3; do + if git push; then + echo "pushed on attempt $attempt" + exit 0 + fi + echo "push rejected on attempt $attempt, rebasing" + git fetch origin main + if git rebase origin/main; then + continue + fi + git rebase --abort || true + echo "rebase conflict; sibling run has the authoritative INTEGRITY.md" + exit 0 + done + echo "gave up after 3 attempts; sibling run likely already refreshed" + exit 0 + +concurrency: + group: integrity-main + cancel-in-progress: false From 69dc670dcdf948a1735206e2f6d34d1727940513 Mon Sep 17 00:00:00 2001 From: Waschtl904 Date: Thu, 10 Sep 2026 15:03:49 +0000 Subject: [PATCH 2/3] ci(integrity): recompute-and-verify, drop unsafe rebase; scope attribution language - Workflow rewrite: always fetch fresh origin/main, rebuild manifest from that snapshot, self-verify with scripts/verify_integrity.sh, publish fast-forward only. Never rebase a pre-built manifest. - On persistent push rejection: fetch remote and verify remote manifest against remote sources; fail loud if it does not match. - Add scripts/build_integrity.sh (deterministic, no timestamp) and scripts/verify_integrity.sh (byte-exact check). - Add workflow file and scripts to paths filter so this PR itself triggers the workflow. - .canary: acknowledge that a token hit is an investigative lead, not a training-data proof. - ATTRIBUTION.md: scope CC-BY-4.0 attribution claim to expression covered by copyright; explicit statement that markers are not cryptographic signatures. --- .canary | 10 ++- .github/workflows/integrity.yml | 125 ++++++++++++++------------------ ATTRIBUTION.md | 25 ++++++- INTEGRITY.md | 13 +++- scripts/build_integrity.sh | 55 ++++++++++++++ scripts/verify_integrity.sh | 25 +++++++ 6 files changed, 174 insertions(+), 79 deletions(-) create mode 100755 scripts/build_integrity.sh create mode 100755 scripts/verify_integrity.sh diff --git a/.canary b/.canary index c71af3f7..0e609832 100644 --- a/.canary +++ b/.canary @@ -12,9 +12,13 @@ Kanonischer Speicherort dieses Markers: /.canary im Repository-Root. canary-id: 065e27e9-900e-7dd8-51b1-f4feb7303ca2 canary-token-sha256: 065e27e9900e7dd851b1f4feb7303ca2f913de6bf2fe8fb758e5ae0df42dc097 -Wenn dieser Token in einem Modelloutput, einem Trainingsdatensatz, -einem Fork, einem Suchindex oder in einer wissenschaftlichen Publikation -auftaucht, ist die Herkunft aus diesem Repository eindeutig belegbar. +Wenn dieser Token in einem Fork, einem Suchindex, einem Trainingsdatensatz, +einem Modelloutput oder einer wissenschaftlichen Publikation auftaucht, +ist das ein Untersuchungsansatz und ein starkes Indiz fuer den Bezug auf +dieses Repository. Ein Treffer ist jedoch kein Beweis fuer den +Uebertragungsweg: schon ein Prompt, der diesen oeffentlichen Marker +enthaelt, kann ihn in einem Modelloutput reproduzieren. Fuer Trainings- +daten-Aussagen sind zusaetzliche Nachweise noetig. Dieses File ist bewusst hier abgelegt. Es ist kein Fehler, kein versehentlich veröffentlichter Schlüssel und keine funktionierende diff --git a/.github/workflows/integrity.yml b/.github/workflows/integrity.yml index 7462e5ec..b9b6cd96 100644 --- a/.github/workflows/integrity.yml +++ b/.github/workflows/integrity.yml @@ -15,8 +15,20 @@ on: - "CITATION.cff" - "LICENSE" - "tests/fixtures/dummy_credentials.json" + # Workflow-Datei selbst mit aufnehmen, damit Änderungen am + # Publikationspfad garantiert einen Lauf auslösen. + - ".github/workflows/integrity.yml" + - "scripts/build_integrity.sh" + - "scripts/verify_integrity.sh" workflow_dispatch: {} +# Koordinieren nur teilnehmender Workflow-Laeufe untereinander; ersetzt +# keine korrekte Veroeffentlichung. Ein wartender Lauf wird nicht +# frueher abgebrochen. +concurrency: + group: integrity-main + cancel-in-progress: false + permissions: contents: write @@ -24,86 +36,61 @@ jobs: refresh-integrity: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - name: Checkout main tip explicitly + uses: actions/checkout@v4 with: + ref: main fetch-depth: 0 persist-credentials: true - - name: Recompute INTEGRITY.md + - name: Recompute-and-publish loop shell: bash + env: + GIT_AUTHOR_NAME: "github-actions[bot]" + GIT_AUTHOR_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com" + GIT_COMMITTER_NAME: "github-actions[bot]" + GIT_COMMITTER_EMAIL: "41898282+github-actions[bot]@users.noreply.github.com" run: | set -euo pipefail - FILES=( - "papers/P11_Global_Coupling_and_Object_X_Candidate_Geometry.tex" - "papers/P11_sections/P11_O3af_Gamma_Symbol_Bridge.tex" - "00-uebersicht/OBJEKT_X_AKTUELLE_ARBEITSDEFINITION.md" - "00-grundlegung/ebene-XVI-objekt-x.md" - "00-uebersicht/ACTIVE_THEOREM_REGISTRY.md" - ".canary" - "ATTRIBUTION.md" - "SECURITY.md" - "CITATION.cff" - "LICENSE" - "tests/fixtures/dummy_credentials.json" - ) - NOW=$(date -u +"%Y-%m-%dT%H:%M:%SZ") - { - echo "# INTEGRITY.md — Hashbaum der Kernddateien" - echo - echo "Zuletzt aktualisiert: ${NOW}" - echo - echo "Diese Datei wird durch den Workflow \`.github/workflows/integrity.yml\` bei jedem Push automatisch aktualisiert." - echo "Jede Zeile enthält die SHA-256-Prüfsumme einer intellektuellen Kronjuwel-, Attributions- oder Canary-Datei." - echo - echo "| Datei | SHA-256 |" - echo "|---|---|" - for f in "${FILES[@]}"; do - if [ -f "$f" ]; then - H=$(sha256sum "$f" | awk '{print $1}') - echo "| \`$f\` | \`$H\` |" - else - echo "| \`$f\` | MISSING |" - fi - done - echo - echo "Reproduktion:" - echo - echo '```' - echo "sha256sum ${FILES[*]}" - echo '```' - } > INTEGRITY.md + git config user.name "$GIT_AUTHOR_NAME" + git config user.email "$GIT_AUTHOR_EMAIL" - - name: Commit if changed - shell: bash - run: | - set -euo pipefail - if git diff --quiet -- INTEGRITY.md; then - echo "INTEGRITY.md unchanged." - exit 0 - fi - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - git add INTEGRITY.md - git commit -m "chore(integrity): refresh INTEGRITY.md hash tree" - # Robust against concurrent runs: rebase-and-retry, then bail - # gracefully if a sibling run already pushed a newer hash tree. for attempt in 1 2 3; do - if git push; then - echo "pushed on attempt $attempt" + echo "== attempt $attempt ==" + # Immer frischen main-Stand holen und darauf zuruecksetzen. + git fetch --quiet origin main + git checkout --quiet -B main origin/main + + # Manifest AUS DIESEM Snapshot neu berechnen. + bash scripts/build_integrity.sh > INTEGRITY.md + + # Sofortige Selbstpruefung: Manifest muss zu Quellen passen. + bash scripts/verify_integrity.sh INTEGRITY.md + + if git diff --quiet -- INTEGRITY.md; then + echo "INTEGRITY.md already matches source snapshot; nothing to publish." exit 0 fi - echo "push rejected on attempt $attempt, rebasing" - git fetch origin main - if git rebase origin/main; then - continue + + git add INTEGRITY.md + git commit -m "chore(integrity): refresh INTEGRITY.md hash tree" + + if git push origin HEAD:main; then + echo "published on attempt $attempt" + exit 0 fi - git rebase --abort || true - echo "rebase conflict; sibling run has the authoritative INTEGRITY.md" - exit 0 + echo "fast-forward push rejected on attempt $attempt; restart from fresh snapshot" + # Lokalen Commit verwerfen; naechste Runde beginnt neu. + git reset --hard HEAD~1 done - echo "gave up after 3 attempts; sibling run likely already refreshed" - exit 0 -concurrency: - group: integrity-main - cancel-in-progress: false + echo "== gave up after 3 attempts; verify remote independently ==" + # Frischen Snapshot ziehen und Remote-Manifest gegen Remote-Quellen pruefen. + git fetch --quiet origin main + git checkout --quiet -B main origin/main + if bash scripts/verify_integrity.sh INTEGRITY.md; then + echo "remote INTEGRITY.md matches remote sources; accepting sibling publication" + exit 0 + fi + echo "remote INTEGRITY.md does NOT match remote sources" + exit 1 diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 63c85a64..898a8a2e 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -44,9 +44,19 @@ nachvollziehbar. Der Herkunftsnachweis wird zusätzlich getragen durch: ## Kronjuwelen dieses Repositoriums Diese fünf Dateien tragen den intellektuellen Kern des Programms und -sind einzeln signiert. Jeder unattributierte Nachdruck von Passagen -oder Definitionen aus einer dieser Dateien ist ein Verstoß gegen -CC-BY-4.0 § 3(a)(1): +sind einzeln mit einem HTML-/LaTeX-Kommentar-Marker versehen. + +**Reichweite und Grenzen der Attributionspflicht.** Das Repository steht +unter CC-BY-4.0. Fuer die von der Lizenz erfassten Nutzungen (§ 2(a)) +verlangt sie eine ordnungsgemaesse Zuschreibung nach § 3(a). Die Lizenz +laesst gesetzliche Ausnahmen und Schranken (§ 2(a)(2)) ausdruecklich +unberuehrt und aendert das nationale Urheberrecht nicht. Urheberrecht +schuetzt zudem grundsaetzlich die konkrete Ausdrucksform, nicht +mathematische Ideen oder Konzepte als solche; wissenschaftliche +Zitierpflicht und urheberrechtliche Durchsetzbarkeit sind zwei +verschiedene Dinge. Ein unattributierter Nachdruck geschuetzter +Ausdrucksform ohne einschlaegige Schranke ist ein Lizenzverstoss; +nicht jede Uebernahme einer Idee oder Definition ist es. | ID | Datei | Rolle | |---|---|---| @@ -56,6 +66,15 @@ CC-BY-4.0 § 3(a)(1): | EBENE_XVI | [`00-grundlegung/ebene-XVI-objekt-x.md`](00-grundlegung/ebene-XVI-objekt-x.md) | Kanonisches Kontrollblatt, drei Ebenen | | ACTIVE_REGISTRY | [`00-uebersicht/ACTIVE_THEOREM_REGISTRY.md`](00-uebersicht/ACTIVE_THEOREM_REGISTRY.md) | Status-System und Governance-Nomenklatur | +## Was diese Marker sind und was nicht + +Die eingefuegten Kommentarzeilen (UUID, Canary-ID, pre-mark-SHA-256) +sind **Attributionsmarker**, keine kryptografischen digitalen +Signaturen. Sie ermoeglichen Zuordnung, Versionsvergleich und die +Unterscheidung nachtraeglicher Kopien vom eingecheckten Stand. Sie +leisten fuer sich allein keinen authentifizierten Urheberschaftsnachweis; +der aktuelle Bot-Commit ist von GitHub als unsigned ausgewiesen. + ## Kontakt Bei Fragen zu Zitation, Weiterverwendung oder mutmaßlicher Übernahme diff --git a/INTEGRITY.md b/INTEGRITY.md index caf6ca2a..8d94d648 100644 --- a/INTEGRITY.md +++ b/INTEGRITY.md @@ -1,9 +1,13 @@ # INTEGRITY.md — Hashbaum der Kernddateien -Zuletzt aktualisiert: 2026-09-10T04:13:42Z +Dieses Manifest wird durch den Workflow `.github/workflows/integrity.yml` +und das Skript `scripts/build_integrity.sh` deterministisch aus den +unten aufgezaehlten Quelldateien erzeugt und veroeffentlicht. -Diese Datei wird durch den Workflow `.github/workflows/integrity.yml` bei jedem Push automatisch aktualisiert. -Jede Zeile enthält die SHA-256-Prüfsumme einer intellektuellen Kronjuwel-, Attributions- oder Canary-Datei. +Der Inhalt aendert sich ausschliesslich, wenn sich mindestens eine +dieser Quelldateien inhaltlich aendert. Zeitstempel werden bewusst +nicht in das Manifest aufgenommen, damit unveraenderte Quellen kein +neues Manifest erzeugen. | Datei | SHA-256 | |---|---| @@ -22,5 +26,6 @@ Jede Zeile enthält die SHA-256-Prüfsumme einer intellektuellen Kronjuwel-, Att Reproduktion: ``` -sha256sum papers/P11_Global_Coupling_and_Object_X_Candidate_Geometry.tex papers/P11_sections/P11_O3af_Gamma_Symbol_Bridge.tex 00-uebersicht/OBJEKT_X_AKTUELLE_ARBEITSDEFINITION.md 00-grundlegung/ebene-XVI-objekt-x.md 00-uebersicht/ACTIVE_THEOREM_REGISTRY.md .canary ATTRIBUTION.md SECURITY.md CITATION.cff LICENSE tests/fixtures/dummy_credentials.json +bash scripts/build_integrity.sh > INTEGRITY.md +bash scripts/verify_integrity.sh INTEGRITY.md ``` diff --git a/scripts/build_integrity.sh b/scripts/build_integrity.sh new file mode 100755 index 00000000..50b81bb4 --- /dev/null +++ b/scripts/build_integrity.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +# Deterministischer Generator fuer INTEGRITY.md. +# Kein Zeitstempel im Manifest -> das Manifest aendert sich NUR, wenn +# sich mindestens eine der ueberwachten Dateien inhaltlich aendert. +# Zeitstempel wird optional als Kommentar hinter der Tabelle gefuehrt. +set -euo pipefail + +FILES=( + "papers/P11_Global_Coupling_and_Object_X_Candidate_Geometry.tex" + "papers/P11_sections/P11_O3af_Gamma_Symbol_Bridge.tex" + "00-uebersicht/OBJEKT_X_AKTUELLE_ARBEITSDEFINITION.md" + "00-grundlegung/ebene-XVI-objekt-x.md" + "00-uebersicht/ACTIVE_THEOREM_REGISTRY.md" + ".canary" + "ATTRIBUTION.md" + "SECURITY.md" + "CITATION.cff" + "LICENSE" + "tests/fixtures/dummy_credentials.json" +) + +cat <<'HEAD' +# INTEGRITY.md — Hashbaum der Kernddateien + +Dieses Manifest wird durch den Workflow `.github/workflows/integrity.yml` +und das Skript `scripts/build_integrity.sh` deterministisch aus den +unten aufgezaehlten Quelldateien erzeugt und veroeffentlicht. + +Der Inhalt aendert sich ausschliesslich, wenn sich mindestens eine +dieser Quelldateien inhaltlich aendert. Zeitstempel werden bewusst +nicht in das Manifest aufgenommen, damit unveraenderte Quellen kein +neues Manifest erzeugen. + +| Datei | SHA-256 | +|---|---| +HEAD + +for f in "${FILES[@]}"; do + if [ -f "$f" ]; then + H=$(sha256sum -- "$f" | awk '{print $1}') + printf "| \`%s\` | \`%s\` |\n" "$f" "$H" + else + printf "| \`%s\` | MISSING |\n" "$f" + fi +done + +cat <<'TAIL' + +Reproduktion: + +``` +bash scripts/build_integrity.sh > INTEGRITY.md +bash scripts/verify_integrity.sh INTEGRITY.md +``` +TAIL diff --git a/scripts/verify_integrity.sh b/scripts/verify_integrity.sh new file mode 100755 index 00000000..ba56b229 --- /dev/null +++ b/scripts/verify_integrity.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Prueft, ob ein uebergebenes INTEGRITY.md exakt zu den aktuell im +# Arbeitsbaum vorhandenen Quelldateien passt. Exit 0 bei Uebereinstimmung. +set -euo pipefail + +MANIFEST="${1:-INTEGRITY.md}" +if [ ! -f "$MANIFEST" ]; then + echo "verify_integrity: manifest not found: $MANIFEST" >&2 + exit 2 +fi + +# Erwartetes Manifest aus dem aktuellen Snapshot neu erzeugen und +# byte-genau vergleichen. Zeitstempellos, also stabil vergleichbar. +EXPECTED=$(mktemp) +trap 'rm -f "$EXPECTED"' EXIT +bash scripts/build_integrity.sh > "$EXPECTED" + +if diff -u "$EXPECTED" "$MANIFEST" >/dev/null; then + echo "verify_integrity: OK ($MANIFEST matches current source snapshot)" + exit 0 +fi + +echo "verify_integrity: MISMATCH ($MANIFEST does not match current sources)" >&2 +diff -u "$EXPECTED" "$MANIFEST" >&2 || true +exit 1 From ebaa488a17137c9a2d4eaf2576f7259cbf2bc913 Mon Sep 17 00:00:00 2001 From: Waschtl904 Date: Thu, 10 Sep 2026 16:30:37 +0000 Subject: [PATCH 3/3] ci(integrity): fail on missing sources, publish new manifest, drop MISSING branch - build_integrity.sh: pre-flight check exits 1 on any missing/unreadable required file; MISSING row removed. - workflow: 'git add -- INTEGRITY.md' before 'git diff --cached --quiet' so a newly created (untracked) manifest is actually published; add INTEGRITY.md itself to paths filter so manifest-only edits trigger. - workflow comment: correct scope of cancel-in-progress: false. - ATTRIBUTION.md: HTML-/LaTeX-Kommentar-Marker + cross-ref to scope section. - INTEGRITY.md: regenerated from the full PR snapshot; .canary and ATTRIBUTION.md hash rows now match the actual head bytes. --- .github/workflows/integrity.yml | 18 +++++++++++++----- ATTRIBUTION.md | 3 ++- INTEGRITY.md | 4 ++-- scripts/build_integrity.sh | 19 +++++++++++++------ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/.github/workflows/integrity.yml b/.github/workflows/integrity.yml index b9b6cd96..e5eda3ae 100644 --- a/.github/workflows/integrity.yml +++ b/.github/workflows/integrity.yml @@ -20,11 +20,15 @@ on: - ".github/workflows/integrity.yml" - "scripts/build_integrity.sh" - "scripts/verify_integrity.sh" + # INTEGRITY.md selbst, damit auch reine Manifest-Aenderungen + # (z. B. Nachpflegen von Hashwerten) einen Lauf ausloesen. + - "INTEGRITY.md" workflow_dispatch: {} -# Koordinieren nur teilnehmender Workflow-Laeufe untereinander; ersetzt -# keine korrekte Veroeffentlichung. Ein wartender Lauf wird nicht -# frueher abgebrochen. +# Koordiniert teilnehmende Workflow-Laeufe untereinander; ersetzt keine +# korrekte Veroeffentlichung. cancel-in-progress: false schuetzt den +# gerade laufenden Job; in der Standard-Warteschlange kann jedoch ein +# neuer wartender Lauf einen bereits wartenden ersetzen. concurrency: group: integrity-main cancel-in-progress: false @@ -67,12 +71,16 @@ jobs: # Sofortige Selbstpruefung: Manifest muss zu Quellen passen. bash scripts/verify_integrity.sh INTEGRITY.md - if git diff --quiet -- INTEGRITY.md; then + # Erst aufnehmen, dann vorgemerkte Aenderungen pruefen. + # git diff -- erkennt untracked new files nicht; + # ein fehlendes Remote-INTEGRITY.md wuerde sonst faelschlich + # als "nichts zu tun" gemeldet. + git add -- INTEGRITY.md + if git diff --cached --quiet -- INTEGRITY.md; then echo "INTEGRITY.md already matches source snapshot; nothing to publish." exit 0 fi - git add INTEGRITY.md git commit -m "chore(integrity): refresh INTEGRITY.md hash tree" if git push origin HEAD:main; then diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 898a8a2e..ace9c7b8 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -38,8 +38,9 @@ nachvollziehbar. Der Herkunftsnachweis wird zusätzlich getragen durch: - die kryptografische Canary-Datei [`/.canary`](.canary), - den fortlaufend aktualisierten Hashbaum der Kernddateien in [`INTEGRITY.md`](INTEGRITY.md), -- die individuellen HTML-Kommentar-Signaturen in den fünf +- die individuellen HTML-/LaTeX-Kommentar-Marker in den fünf „Kronjuwelen“-Dateien (siehe Abschnitt unten). + Zur Reichweite und Grenze siehe unten „Was diese Marker sind und was nicht“. ## Kronjuwelen dieses Repositoriums diff --git a/INTEGRITY.md b/INTEGRITY.md index 8d94d648..41828353 100644 --- a/INTEGRITY.md +++ b/INTEGRITY.md @@ -16,8 +16,8 @@ neues Manifest erzeugen. | `00-uebersicht/OBJEKT_X_AKTUELLE_ARBEITSDEFINITION.md` | `19d3cdc076dbc65204e68eff2962291c4f15663d2f8cce4d7b4fc29a1941ddbe` | | `00-grundlegung/ebene-XVI-objekt-x.md` | `2dd5ae5565ec7a34a2a474bf01d8411b85a10777800349281428127f95c8ca9d` | | `00-uebersicht/ACTIVE_THEOREM_REGISTRY.md` | `8c7f0b69d7326e074e6b4db2ab967cc2d59bbe24026353b63c49deda9700aaba` | -| `.canary` | `dd23f298793df6a9142e793ef23010ac6a2683a8603c33638fb346f2b9c366e1` | -| `ATTRIBUTION.md` | `497f63305df3bae4e72f1c71f293561671cbe77f711828c6f66aef3f8acac640` | +| `.canary` | `e6c1afe34a565abf999843248c4fadaf1e55ae1ecd3bb1e8b009b872dfc00ba5` | +| `ATTRIBUTION.md` | `75f9fb7653c73d93731e41d131939ea9157f51b734edb4d525b060fbe8741230` | | `SECURITY.md` | `1b3726621bc6a9de6e9db0887d5f3a855e38d26f0ac7f5a854cd6f6431db8833` | | `CITATION.cff` | `67e04f14734e1128a2bc99ef322dbfb751c343389a6b360372ce063f049e67fe` | | `LICENSE` | `9ba9550ad48438d0836ddab3da480b3b69ffa0aac7b7878b5a0039e7ab429411` | diff --git a/scripts/build_integrity.sh b/scripts/build_integrity.sh index 50b81bb4..53250f30 100755 --- a/scripts/build_integrity.sh +++ b/scripts/build_integrity.sh @@ -19,6 +19,17 @@ FILES=( "tests/fixtures/dummy_credentials.json" ) +# Pflichtdateiprüfung VOR jeder Manifestausgabe: fehlt eine Eingabe +# oder ist sie unlesbar, muss der Generator fehlschlagen. Eine gültige +# Beschreibung einer fehlenden Datei ist kein Integritätsnachweis. +for f in "${FILES[@]}"; do + if [[ ! -f "$f" || ! -r "$f" ]]; then + printf 'build_integrity: required file missing or unreadable: %s\n' \ + "$f" >&2 + exit 1 + fi +done + cat <<'HEAD' # INTEGRITY.md — Hashbaum der Kernddateien @@ -36,12 +47,8 @@ neues Manifest erzeugen. HEAD for f in "${FILES[@]}"; do - if [ -f "$f" ]; then - H=$(sha256sum -- "$f" | awk '{print $1}') - printf "| \`%s\` | \`%s\` |\n" "$f" "$H" - else - printf "| \`%s\` | MISSING |\n" "$f" - fi + H=$(sha256sum -- "$f" | awk '{print $1}') + printf "| \`%s\` | \`%s\` |\n" "$f" "$H" done cat <<'TAIL'