grok-bot 9b5db2d3eb Fix: Markdown-Downloads nicht mehr als application/zip ausliefern
Ursache: nginx location /downloads/ mit default_type application/zip —
.md fehlt in mime.types, Browser speichern Listen als .zip.

- fulfill/nginx.snippet.conf: types für zip/md/txt/pdf, default octet-stream
- HTML: download="<dateiname>.md" an allen Markdown-Links (33)
- HANDOFF Abschnitt 13, README-Hinweis

Live-Site-Config (/etc/nginx/sites-available/ki-buch-archive) braucht
noch sudo-Anpassung + nginx reload; nicht in diesem Commit.
2026-11-09 09:17:01 +01:00

KI-Buch-Archive

Statische Website für Begleit-Service und Downloads zu den KI-Praxisbüchern.

Domain: https://books.maatini.space

Kein Shop, kein CMS – HTML/CSS, versionierte Hinweise und ZIP-Dateien. JavaScript ist nicht nötig für die Kerninhalte.

Buch-PDFs sind nicht öffentlich. Berechtigte Adressen fordern unter /beziehen.html einen Link an; der Versand läuft über einen kleinen Python-Dienst auf dem Host.


Struktur

ki-buch-archive/               # Repo-Name; Domain: books.maatini.space
├── index.html                 # Hub: Projektliste
├── beziehen.html              # Buch-PDF: E-Mail + Titel
├── impressum.html             # Anbieterangaben (§ 5 DDG)
├── css/styles.css
├── fulfill/                   # Allowlist-Versand (Python 3, stdlib)
├── private/                   # Allowlist + PDFs (nicht im Git, außer Beispiele)
├── content/
│   ├── was-bleibt-vom-menschen/  # Autor-Quellen (status, errata, Checklisten)
│   ├── ki-hinterm-vorhang/    # Autor-Quellen (status, errata, Checklisten)
│   ├── claude-code-harness/   # Autor-Quellen (status, errata, drift, Pflege)
│   ├── copilot-cli-harness/
│   ├── codex-harness/
│   ├── coding-agents-praxis/
│   └── agents-angular-spring-quarkus/
├── projects/
│   ├── was-bleibt-vom-menschen/  # Begleit-Service Hub + Unterseiten (Sachbuch)
│   ├── ki-hinterm-vorhang/    # Begleit-Service Hub + Unterseiten (Sachbuch)
│   ├── claude-code-harness/   # Begleit-Service Hub + Unterseiten
│   ├── copilot-cli-harness/
│   ├── codex-harness/
│   ├── coding-agents-praxis/
│   └── agents-angular-spring-quarkus/
├── downloads/
│   ├── was-bleibt-vom-menschen/
│   ├── ki-hinterm-vorhang/
│   ├── claude-code-harness/
│   ├── copilot-cli-harness/
│   ├── codex-harness/
│   ├── coding-agents-praxis/
│   └── agents-angular-spring-quarkus/
├── scripts/
│   ├── pack-was-bleibt-vom-menschen.sh
│   ├── pack-ki-hinterm-vorhang.sh
│   ├── pack-claude-code-harness.sh
│   ├── pack-copilot-cli-harness.sh
│   ├── pack-codex-harness.sh
│   ├── pack-coding-agents-praxis.sh
│   └── pack-agents-angular-spring-quarkus.sh
└── CNAME                      # books.maatini.space
URL Inhalt
/ Projektübersicht
/beziehen.html Buch-PDF per E-Mail (Allowlist)
/impressum.html Impressum
/projects/was-bleibt-vom-menschen/ Begleit-Service Was bleibt vom Menschen? (Sachbuch)
/projects/ki-hinterm-vorhang/ Begleit-Service Die KI hinter dem Vorhang (Sachbuch)
/projects/claude-code-harness/ Begleit-Service Claude (Stand, Errata, Material, Hilfe, …)
/projects/copilot-cli-harness/ Begleit-Service Copilot CLI (Stand, Errata, Material, Hilfe, …)
/projects/codex-harness/ Begleit-Service Codex (Stand, Errata, Material, Hilfe, …)
/projects/coding-agents-praxis/ Begleit-Service Coding Agents in der Praxis (Stand, Errata, Material, …)
/projects/agents-angular-spring-quarkus/ Begleit-Service Agents mit Angular, Spring Boot & Quarkus
/downloads/<slug>/*.zip Mitmach-Material
/downloads/<slug>/MANIFEST.txt SHA256 und material-Version
/downloads/<slug>/*.md Markdown-Spiegel (MIME text/markdown, siehe fulfill/nginx.snippet.conf)

Versionierung

ID Bedeutung Beispiel Menschen Beispiel Vorhang Beispiel Claude Beispiel Copilot Beispiel Codex Beispiel Praxis Beispiel EIT
Buchstand Faktenlage im Druck/PDF Oktober 2026 Oktober 2026 Juli 2026 Juli 2026 Mitte/Ende 2026 August 2026 August 2026
companion Website-Inhaltsstand companion-0.1.2 companion-0.1.12 companion-0.1.2 companion-0.1.1 companion-0.1.1 companion-0.1.6 companion-0.1.0
material Paketstand material-2026-10-31 material-2026-11-01 material-2026-07-29 material-2026-07-30 material-2026-07-31 material-2026-11-07 material-2026-08-08

Nach Änderungen an content/<slug>/status.yaml (companion, Ampel, Prüfdatum) die HTML-Badges spiegeln:

python3 scripts/sync-companion-status.py
python3 scripts/sync-companion-status.py --check

Das Script schreibt Hub-Tags, Statuskarten (Prüfstatus), reviewed-line und Lesevertrag-Fuß. Changelog-Historie, SHA256 und Paketstand-Karten bleiben unberührt.

listed: false in status.yaml: keine Hub-Karte, keine Option unter /beziehen.html. Projektseiten, Downloads und Fulfill-Slug bleiben. Default ist gelistet.

Autor-Checklisten:

  • content/was-bleibt-vom-menschen/status.yaml · MAINTENANCE.md
  • content/ki-hinterm-vorhang/status.yaml · MAINTENANCE.md
  • content/claude-code-harness/status.yaml · MAINTENANCE.md
  • content/copilot-cli-harness/status.yaml · MAINTENANCE.md
  • content/codex-harness/status.yaml · MAINTENANCE.md
  • content/coding-agents-praxis/status.yaml · MAINTENANCE.md
  • content/agents-angular-spring-quarkus/status.yaml · MAINTENANCE.md

Typ-Unterscheidung auf der Site:

  • Erratum – Fehler im Buch
  • Produkt-Drift – Produkt/Doku hat sich geändert
  • Vereinfachung – bewusst knapper im Buch, nicht falsch

ZIPs neu packen

was-bleibt-vom-menschen

Sachbuch: Quellen liegen in content/was-bleibt-vom-menschen/ (keine Coding-Vorlagen aus einem Sibling-Repo). Packt vier Markdown-Spiegel plus checklisten.zip.

MATERIAL_VERSION=material-2026-10-31 COMPANION_VERSION=0.1.1 \
  ./scripts/pack-was-bleibt-vom-menschen.sh

ki-hinterm-vorhang

Sachbuch: Quellen liegen in content/ki-hinterm-vorhang/ (keine Coding-Vorlagen aus einem Sibling-Repo). Packt vier Markdown-Spiegel plus checklisten.zip.

MATERIAL_VERSION=material-2026-11-01 COMPANION_VERSION=0.1.12 \
  ./scripts/pack-ki-hinterm-vorhang.sh

claude-code-harness

Voraussetzung: Sibling-Buch-Repo (Standard ../ki-claude, Override BOOK_ROOT oder historisch KI_CLAUDE_ROOT).

CLAUDE_CODE_TESTED=2.1.220 ./scripts/pack-claude-code-harness.sh
MATERIAL_VERSION=material-2026-07-29 CLAUDE_CODE_TESTED=2.1.220 ./scripts/pack-claude-code-harness.sh

copilot-cli-harness

Voraussetzung: Sibling-Buch-Repo (Standard ../ki-copilot, Override BOOK_ROOT oder KI_COPILOT_ROOT).

COPILOT_CLI_TESTED=1.0.76 ./scripts/pack-copilot-cli-harness.sh
MATERIAL_VERSION=material-2026-07-30 COPILOT_CLI_TESTED=1.0.76 ./scripts/pack-copilot-cli-harness.sh

codex-harness

Voraussetzung: Sibling-Buch-Repo (Standard ../ki-codex, Override BOOK_ROOT oder KI_CODEX_ROOT).

CODEX_CLI_TESTED=0.146.0 ./scripts/pack-codex-harness.sh
MATERIAL_VERSION=material-2026-07-31 CODEX_CLI_TESTED=0.146.0 ./scripts/pack-codex-harness.sh

coding-agents-praxis

Voraussetzung: Sibling-Buch-Repo (Standard ../ki-coding-agents-praxis, sonst historisch ../ki-praxis; Override BOOK_ROOT oder KI_PRAXIS_ROOT). Packt templates/ → vorlagen.zip, checklists/ → checklisten.zip und Anhang B (manuskript/kapitel-24-anhang-b-stack-orientierung.md, Fallback 24-anhang-b-stack-orientierung.md) → stack-orientierung.md (vendor-agnostisch).

./scripts/pack-coding-agents-praxis.sh
MATERIAL_VERSION=material-2026-11-07 COMPANION_VERSION=0.1.6 ./scripts/pack-coding-agents-praxis.sh

agents-angular-spring-quarkus

Voraussetzung: Sibling-Buch-Repo (Standard ../ki-eit, Override BOOK_ROOT oder KI_EIT_ROOT). Packt templates/ → vorlagen.zip, checklists/ → checklisten.zip, 15-anhang-b-command-referenz.md → command-referenz.md und 16-anhang-c-agent-mapping.md → agent-mapping.md.

./scripts/pack-agents-angular-spring-quarkus.sh
MATERIAL_VERSION=material-2026-08-08 COMPANION_VERSION=0.1.0 ./scripts/pack-agents-angular-spring-quarkus.sh

Erzeugt jeweils downloads/<slug>/… und MANIFEST.txt (Menschen / Vorhang: vier Markdown-Spiegel + checklisten.zip; Harness-Bücher: beispiele.zip + vorlagen.zip; Praxis: vorlagen.zip + checklisten.zip + Stack-Spiegel; EIT: vorlagen.zip + checklisten.zip + Command-/Mapping-Spiegel). Danach SHA256 und Versionsstring auf Hub + Material-Seite anpassen, wenn sie sich ändern.

Ausschlüsse u. a.: __pycache__, .venv, *.egg-info, .DS_Store.


Lokal prüfen

cd /pfad/zu/ki-buch-archive
python3 -m http.server 8080
# → http://127.0.0.1:8080/projects/was-bleibt-vom-menschen/
# → http://127.0.0.1:8080/projects/ki-hinterm-vorhang/
# → http://127.0.0.1:8080/projects/claude-code-harness/
# → http://127.0.0.1:8080/projects/copilot-cli-harness/
# → http://127.0.0.1:8080/projects/codex-harness/
# → http://127.0.0.1:8080/projects/coding-agents-praxis/
# → http://127.0.0.1:8080/projects/agents-angular-spring-quarkus/

Ohne JS navigieren; Badge und Lesevertrag-Fuß auf jeder Projektseite prüfen.


Neues Projekt hinzufügen

  1. projects/<slug>/index.html anlegen
  2. downloads/<slug>/… mit ZIPs füllen (eigenes Pack-Script optional)
  3. Karte auf der Hauptseite index.html ergänzen
  4. Bei Buch-PDF-Versand: Slug in fulfill/server.py (BOOKS), Option in beziehen.html, PDF nach private/books/<slug>.pdf

Kein Framework-Umbau nötig. Begleit-Service-Unterseiten (Stand/Errata/…) nur, wenn das Buch denselben Pflege-Vertrag braucht.


Buch-PDF per E-Mail

Kein öffentlicher PDF-Pfad. Ablauf:

  1. Formular /beziehen.html (E-Mail + Titel) → POST /api/beziehen

  2. Treffer in private/allowlist.txt (eine Zeile pro Titel: Exact-Adresse oder Pattern, dann Slug). Sichtbare Optionen: was-bleibt-vom-menschen, ki-hinterm-vorhang, coding-agents-praxis. Die übrigen Slugs in fulfill/server.py (BOOKS) bleiben gültig, auch wenn listed: false.

    • ada@example.com slug — eine Adresse
    • *@edeka.de slug — alle Postfächer an genau @edeka.de
    • *.edeka.de slug — @edeka.de und Subdomains (@markt.edeka.de)

    Matching über DNS-Labels, nicht String-Ende (not-edeka.de trifft *.edeka.de nicht). Muster mit nur einer Label-Stufe (*.de, *@de) und Catch-alls (*, *@*) matchen nicht.

  3. HMAC-Link 24 Stunden an diese Adresse (GET /d/<token>)

  4. Unbekannte Adressen: dieselbe Bestätigung, keine Mail

Allowlist und PDFs liegen außerhalb des Webroots-Git:

private/allowlist.txt          # aus allowlist.example.txt
private/books/<slug>.pdf

Tests:

python3 -m unittest fulfill.test_server

Lokal (ohne echten SMTP, Mailer schlägt fehl – die HTTP-Bestätigung bleibt gleich):

export FULFILL_SECRET=lokal-test-secret-16
export FULFILL_ROOT=.
python3 fulfill/server.py

Produktion: Env nach /etc/ki-buch-archive/fulfill.env (Vorlage fulfill/fulfill.env.example), Unit fulfill/ki-buch-fulfill.service, nginx-Snippet fulfill/nginx.snippet.conf (/api/ und /d/ nach 127.0.0.1:8787). Statische Dateien weiter aus diesem Verzeichnis.


Deploy

Artefakt = dieses Verzeichnis (statisch) plus der Fulfill-Dienst für /api/ und /d/.

  1. DNS: books.maatini.space → dein Host (GitHub Pages, Cloudflare Pages, nginx-Root, …)
  2. Dateien so ausliefern, dass index.html an der Domain-Root liegt
  3. CNAME-Datei ist für GitHub Pages bereits gesetzt (books.maatini.space)

Redirects (empfohlen am Host):

Alt Neu
/projects/ki-claude/* /projects/claude-code-harness/*
/downloads/ki-claude/* /downloads/claude-code-harness/*
ki-buch-archive.maatini.space books.maatini.space

Statische Meta-Redirects liegen unter projects/ki-claude/ (HTML). ZIP-Pfade brauchen Host-301.


Buch-Verweise

Buch-Repo Begleit-Service
zukunft (Was bleibt vom Menschen?) https://books.maatini.space/projects/was-bleibt-vom-menschen/
ki-hinterm-vorhang https://books.maatini.space/projects/ki-hinterm-vorhang/
ki-claude https://books.maatini.space/projects/claude-code-harness/
ki-copilot https://books.maatini.space/projects/copilot-cli-harness/
ki-codex https://books.maatini.space/projects/codex-harness/
ki-coding-agents-praxis (historisch ki-praxis) https://books.maatini.space/projects/coding-agents-praxis/
ki-eit https://books.maatini.space/projects/agents-angular-spring-quarkus/

Dort: Stand, Errata, aktuelle ZIPs, Hilfe und Feedback – nicht nur Downloads.

S
Description
No description provided
Readme
3.3 MiB
0 Stars 1 Watchers 0 Forks
Languages
HTML 83.5%
Python 7.4%
Shell 5.2%
CSS 3.9%