Initialer Stand: Collatz-Sachbuch
Forschungsbasis docs/ (Faktenkanon mit Referenzen), Wissensbasis docs/kb/ (Recherche-Router, Video-Inhaltskarte), Buchstruktur 00-inhaltsverzeichnis.md (Kapitelbogen 0-13, Labels, Flags), Build-Pipeline (justfile, scripts, pdf-Templates), Projektregeln (AGENTS.md, HANDOFF), Lint-/Link-Checks, Command-Code-Skills. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
commit
1b978a3062
61 files changed
+6584
No files matched your search
@@ -0,0 +1,36 @@
|
||||
---
|
||||
description: Überblick über das Buch-Repo — Manuskript, Forschungsbasis, Knowledge, Harness
|
||||
argument-hint: ""
|
||||
---
|
||||
# Status des Buch-Repos
|
||||
|
||||
1. **Manuskript** im Root prüfen:
|
||||
- `00-inhaltsverzeichnis.md` (Navigation, nicht im PDF) — vorhanden? Kapitel-Labels verbindlich?
|
||||
- `NN-*.md`-Kapitel — welche vorhanden, welche fehlen laut Inhaltsverzeichnis?
|
||||
2. **Forschungsbasis:**
|
||||
- `docs/` — alle 10 Dateien (`01`–`09` + `index.md`) vorhanden? `docs/08-references.md` als alleiniges URL-Ziel?
|
||||
- Unverändert gegen letzten Commit (`git diff --stat docs/`)?
|
||||
3. **Autoren-Harness:**
|
||||
- `AGENTS.md` (schlank, always-on, inkl. Schreibkonventionen-Import)
|
||||
- `.commandcode/rules/schreibkonventionen.md`
|
||||
- Skills: `lektorat`, `kapitel-review`, `humanizer`, `abbildung`, `total-check`, `pdf-bauen`, `pdf-print`
|
||||
- Commands: `/buch-status`, `/gegenlese`, `/pdf`
|
||||
- Pipeline-Reference nur on demand: `.commandcode/skills/pdf-bauen/references/pipeline.md`
|
||||
4. **Knowledge:** `docs/kb/INDEX.md` vorhanden? Nicht den ganzen Tree vorladen.
|
||||
5. **Meta:** `HANDOFF-collatz.md` vorhanden? `kladde.md` unangetastet.
|
||||
6. **Abbildungen:** `assets/` — falls vorhanden: Katalog? (Aktuell: noch keine Figuren.)
|
||||
7. **PDF-Pipeline:** `justfile`, `scripts/`, `pdf/` vorhanden? Optional Dist-mtime vs. Manuskript — **nicht** ungefragt bauen.
|
||||
|
||||
Ausgabe als Tabelle:
|
||||
|
||||
| Bereich | Status | Hinweis |
|
||||
|---------|--------|---------|
|
||||
| Manuskript + TOC | … | welche Kapitel fehlen |
|
||||
| Forschungsbasis (`docs/`) | … | vollständig / Änderungen? |
|
||||
| Autoren-Harness | … | Rules/Skills/Commands |
|
||||
| Knowledge | … | INDEX + Domains |
|
||||
| Abbildungen | … | Stand |
|
||||
| PDF-Pipeline | vorhanden / … | Build nur auf Auftrag; PDF ggf. älter als Manuskript |
|
||||
| Meta (HANDOFF) | … | … |
|
||||
|
||||
Dann 1–3 sinnvolle nächste Schritte vorschlagen (ohne ungefragt zu bauen, zu committen oder zu lektorieren).
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
description: Kritische Gegenlese eines Kapitels (Argumentation, Lesefluss, Substanz, Ton)
|
||||
argument-hint: "01-einfuehrung.md"
|
||||
---
|
||||
# Kapitel-Gegenlese
|
||||
|
||||
Führe den Review-Skill aus. Lade `.commandcode/skills/kapitel-review/SKILL.md`.
|
||||
|
||||
Kapitel als Argument. Fehlt es: nachfragen. Keine automatischen Manuskript-Edits.
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
description: Baut das Buch-PDF und führt QA durch. Optionen: full (default), draft, plain
|
||||
argument-hint: "[full|draft|plain]"
|
||||
---
|
||||
# PDF bauen und prüfen
|
||||
|
||||
Führe den PDF-Bau-Skill aus. Lade `.commandcode/skills/pdf-bauen/SKILL.md`.
|
||||
|
||||
Argument: Build-Art (`full` = Standard, `draft` = Wasserzeichen, `plain` = ohne gestyltes Template).
|
||||
Nach full-Build QA mit `just qa`, sofern nicht anders gewünscht.
|
||||
@@ -0,0 +1,100 @@
|
||||
# Schreibkonventionen — Die Collatz-Vermutung (Sachbuch)
|
||||
|
||||
Ergänzt `AGENTS.md` um detaillierte Schreib-, Ton- und Formatierungsregeln fürs Manuskript.
|
||||
|
||||
---
|
||||
|
||||
## Ton und Sprache
|
||||
|
||||
### Grundhaltung
|
||||
|
||||
- **Verlässlicher Erklärer:** präzise, geduldig, ehrlich. Neugier wecken, nicht bedienen.
|
||||
- Kein Hype, keine Sensationsgier, keine Panik-Mathematik („es könnte alles zusammenbrechen“).
|
||||
- Offene Fragen als offene Fragen behandeln — das ist die spannendeste Stelle des Buchs, nicht die unangenehme.
|
||||
- Aktive, konkrete Sätze. Jeder Absatz soll Neugier stifen oder Verständnis sichern.
|
||||
|
||||
### Stil
|
||||
|
||||
- Deutsch durchgängig; Personennamen und Fachbegriffe original (Collatz, Erdős, Lagarias, Tao; *stopping time*, *logarithmic density* bei Erstnennung mit Übersetzung).
|
||||
- Kurze, klare Sätze. Schachtelsätze vermeiden.
|
||||
- Jeder Fachbegriff beim ersten Auftreten im Kapitel erklärt — in einem Nebensatz, nicht in einem Exkurs.
|
||||
- „Du“-Ansprache an die Leserschaft ist ok; distanzierendes „man“ wo „Du“ tonal nicht passt.
|
||||
- Rechenbeispiele vor Formeln (erst `n = 7` durchspielen, dann generalisieren); Formeln sparsam und immer umgangssprachlich aufgelöst.
|
||||
- Analogien ausdrücklich als Vergleichshilfe markieren („Ein Bild, kein Beweis“).
|
||||
|
||||
### Vermeiden
|
||||
|
||||
- Floskeln und Füllsätze ohne Handlungs- oder Erkenntnisfolge
|
||||
- Ungefragte Exkurse, Kapitelumstellungen, „interessante Fakten“
|
||||
- Mathematik-Mystifikation: „gelöst!“-Framings, Sensations-Übertreibungen, Genie-Kitsch
|
||||
- Fachbegriffswände ohne Erklärung; ungeklärte Begriffe ab der dritten Verwendung
|
||||
- Zahlen ohne Kontext („2^71“ → „eine Zahl mit 22 Stellen — mehr Atome als das Universum hat“-Kontext geben)
|
||||
- Erfundene Namen, Zitate, Dialoge oder Daten
|
||||
- Gesamtrewrite „aus Prinzip“
|
||||
|
||||
---
|
||||
|
||||
## Terminologie (einheitlich)
|
||||
|
||||
| Begriff | Verwendung | Nicht verwechseln mit |
|
||||
|---------|------------|------------------------|
|
||||
| Collatz-Vermutung | Die offene Frage: landet jede Startzahl am Ende bei 1? | „Collatz-Problem“ (Synonym ok, einmal einführen) |
|
||||
| 3n+1-Problem | Synonym (historische Herkunft) | Syracuse-Problem (nur als Historie) |
|
||||
| Iteration | Ein Schritt der Rechenvorschrift | „Loop“/„Schleife“ als Meta-Begriff |
|
||||
| Orbit / Trajektorie | Die ganze Zahlenfolge ab einer Startzahl | geordnete „Liste“ ohne Richtung |
|
||||
| Shortcut-Map `T` | `T(n) = n/2` (gerade), `(3n+1)/2` (ungerade) | klassische Map (3n+1 **ohne** sofortige Division) — Unterschied einmal zeigen |
|
||||
| Stoppzeit (*stopping time*) | Schritte bis zum ersten Wert **unter** der Startzahl (Terras) | Gesamtstoppzeit (Schritte bis 1); beide benannt, dann konsistent |
|
||||
| Gesamtstoppzeit | Schritte bis 1 | Stoppzeit |
|
||||
| Zyklus (m-Zyklus) | geschlossener Orbit mit m ungeraden Schritten | umgangssprachliche „Endlosschleife“ |
|
||||
| log-Dichte (*logarithmic density*) | Dichtebegriff in Taos Ergebnis (2022) | natürliche Dichte (Terras 1976) — Unterschied einmal nennen |
|
||||
| fast alle | log-Dichte 1 | „alle“ |
|
||||
| 2-adisch | `ℤ₂`, Shift-Konjugation, Erweiterung der Map | „binär“ |
|
||||
| Verifikationsgrenze | `2^71 ≈ 2,36 × 10^21` (Barina, 2025/26) | ein Beweis |
|
||||
| Z-Zahlen | Mahlers Problem zu `(3/2)^n` (1968) | Collatz selbst |
|
||||
| Baker-Theorie | lineare Formen in Logarithmen (Zyklen-Resultate) | ein Beweis der Vermutung |
|
||||
| Undecidability | Conway/Kurtz–Simon für **Generalisierungen** | Undecidability der einzelnen Vermutung (offen) |
|
||||
|
||||
---
|
||||
|
||||
## Kapitel und Abschnitte
|
||||
|
||||
### Erklärungsdichte
|
||||
|
||||
- Tabellen und Listen mit 1–3 Sätzen davor und/oder danach einrahmen.
|
||||
- Pro `###` mindestens ein **Wie** (Mechanik) und ein **Warum** (Bedeutung, offene Frage, Fehlschluss), wo Lehrstoff steckt.
|
||||
- Nach dem Abschnitt soll die Leserschaft in einem Satz sagen können, *warum* der Punkt zählt.
|
||||
|
||||
### Lesbarkeit
|
||||
|
||||
- Pro `###`: Szene, Alltagsbeispiel oder Leserfrage *vor* der Theorie, wo machbar.
|
||||
- Tabelle nur für Vergleich/Nachschlagen; sonst Fließtext, Vorher/Nachher oder Do/Avoid.
|
||||
- Nach Tabelle: 1–2 Sätze Transfer.
|
||||
- Wärme-Bausteine (Szene, Atem, Katalog-Einstieg): on demand `.commandcode/skills/lektorat/references/waerme.md`.
|
||||
|
||||
### Reprise (Kernprinzipien)
|
||||
|
||||
Spiralig wiederkehrend (max. 2–3 explizite Reprisen pro Kapitel am Gelenk):
|
||||
|
||||
1. Ungelöst bleibt ungelöst — keine Ausnahme für Einzelbeobachtungen
|
||||
2. Erst das Beispiel, dann die Formel
|
||||
3. Heuristik ≠ Beweis — Stärke und Grenze der stochastischen Modelle
|
||||
|
||||
- **Kanon** (erster Lehrort): volle Erklärung behalten.
|
||||
- **Nützliche Reprise:** 1 Satz + Brücke + *neuer* Aspekt.
|
||||
- **Echo ohne Mehrwert:** streichen oder auf Verweis kürzen.
|
||||
|
||||
### Abschlüsse
|
||||
|
||||
- Verbindliche Abschluss-Labels pro Kapitel werden im Inhaltsverzeichnis festgelegt (z. B. **Was du mitgenommen hast** / **Der Blick nach vorn**).
|
||||
- Labels sind dann **nicht umbenennbar**.
|
||||
- Abschluss-Abschnitte: `## … {.unnumbered .unlisted}` — **nicht** im PDF-Inhaltsverzeichnis.
|
||||
|
||||
### PDF-Inhaltsverzeichnis
|
||||
|
||||
Satellite-`##`: `{.unnumbered .unlisted}` (beide Marker — nur `.unlisted` bleibt im IV). Details: `.commandcode/skills/pdf-bauen/references/pipeline.md` → „PDF-Inhaltsverzeichnis“. Kein `toc-depth: 2` ohne Auftrag.
|
||||
|
||||
### Faktenbezug
|
||||
|
||||
- Jede Stand- oder Rekordangabe mit Quelle im Text (Autor + Jahr); URL-Ziel liegt in `docs/08-references.md`.
|
||||
- Widerspruch zwischen Manuskript und `docs/` → `docs/` prüfen; wenn `docs/` falsch oder unvollständig: dort korrigieren (mit Quelle), dann Manuskript.
|
||||
- Neu recherchierte Fakten: **erst** `docs/`, dann Manuskript (Faktenschutz, siehe `AGENTS.md`).
|
||||
@@ -0,0 +1,193 @@
|
||||
---
|
||||
name: abbildung
|
||||
description: >
|
||||
Erstellt eine hochauflösende, ansprechende Buch-Abbildung mit einem Bild-Generator
|
||||
(image_gen), prüft sie multimodal gegen Spec/Anforderungen und wiederholt
|
||||
den Prozess bei Mängeln maximal 5-mal. Nutzen bei: „Abbildung erzeugen“,
|
||||
„Figur generieren“, „Illustration für Kapitel X“, „Asset neu“, „Cover bauen“, /abbildung.
|
||||
when-to-use: >
|
||||
User will eine Buch-Figur erzeugen, regenerieren oder gegen Spec prüfen (Figur-ID oder Cover).
|
||||
Nicht für Kapitel-Lektorat und nicht für PDF-Build.
|
||||
argument-hint: "<ID oder freier Spec-Text>"
|
||||
---
|
||||
|
||||
# Abbildung — Imagine + QA-Loop
|
||||
|
||||
Autoren-Skill für *Die Collatz-Vermutung*. Erzeugt **eine** Abbildung (oder bewusstes Regenerieren), speichert sie kanonisch und bricht erst ab, wenn die QA grün ist oder **5 Versuche** ausgeschöpft sind.
|
||||
|
||||
**Bild-Tool:** je nach Host (`image_gen`/`image_edit` oder äquivalent) — Prompt-Craft nach den Imagine-Prinzipien unten.
|
||||
**Katalog / Specs:** ein Figuren-Katalog (`abbildungen.md`, sobald angelegt); Prompt-Dateien optional unter `prompts/`.
|
||||
|
||||
## Prinzipien
|
||||
|
||||
1. **Denken vor dem Schreiben** — Spec und Success-Kriterien explizit, bevor `image_gen`.
|
||||
2. **Einfachheit** — eine Figur pro Lauf; kein Drive-by-Manuskript-Rewrite.
|
||||
3. **Chirurgisch** — nur Asset (+ optional Katalog-Status); Kapitel-Einbettung nur mit Auftrag.
|
||||
4. **Zielgetrieben** — fertig erst bei QA-Pass oder dokumentiertem Fail nach 5 Versuchen.
|
||||
5. **SVG-first bei exakter Struktur** — Zahlenreihen, Ring-Hierarchien, feste Label-Sets: nicht endlos Imagine raten lassen (siehe Gate 0).
|
||||
|
||||
## Gate 0 — Imagine vs. Code/SVG
|
||||
|
||||
| Bedarf | Werkzeug |
|
||||
|--------|----------|
|
||||
| Stimmung, Szene, metaphorische Infografik, weiche Editorial-Grafik | **Imagine** (`image_gen` / ggf. `image_edit`) |
|
||||
| Exakte Label-Reihenfolge, Zahlen, Diagramm-Geometrie, feste Hierarchie | **SVG → JPEG** (`assets/illustrations/_gen/…`) — Imagine max. 1–2 Explorationsversuche, dann SVG |
|
||||
|
||||
Wenn Spec exakte Struktur fordert und Versuch 1–2 klar scheitern → **nicht** bis 5 leerlaufen: ab Versuch 3 auf SVG-Pfad wechseln (oder User fragen).
|
||||
|
||||
## Eingaben klären
|
||||
|
||||
Fehlende Pflichtinfos **nachfragen** (nicht raten):
|
||||
|
||||
| Feld | Pflicht | Default / Hinweis |
|
||||
|------|---------|-------------------|
|
||||
| **Ziel / Thema** | ja | Was muss der Leser in 3 Sek. verstehen? |
|
||||
| **ID** | empfohlen | z. B. `F-01`, `C-01`; neu: mit User abstimmen |
|
||||
| **Kapitel-Anker** | empfohlen | z. B. `03 · §3.2` |
|
||||
| **Caption (DE)** | ja | für Markdown-Einbettung; **nicht** als Bild-Wandtext |
|
||||
| **Labels im Bild** | ja | kurz, **englisch**, max. ~12 kurze Keywords |
|
||||
| **Aspect ratio** | nein | Body **16:9**; Cover oft **2:3** |
|
||||
| **Zielpfad** | nein | `assets/illustrations/<ID>-<slug>.jpg` |
|
||||
| **Prompt-Quelle** | nein | existierende `prompts/**/<ID>-….txt` (falls vorhanden) oder neu formulieren |
|
||||
| **Einbetten** | nein | nur bei explizitem Auftrag Kapitel anfassen |
|
||||
|
||||
Bestehenden Prompt unter `prompts/` **lesen und als Basis** nutzen, wenn die ID dort lebt.
|
||||
|
||||
## Stil-Kanon (Buch)
|
||||
|
||||
Immer im Prompt verankern (positiv formulieren):
|
||||
|
||||
- Clean Infographic / wissenschaftliche Editorial-Illustration
|
||||
- **flat vector + soft depth**
|
||||
- Palette-Anker: deep navy `#0B1F33`, teal `#0D9488`, soft blue `#2563EB`, off-white `#F8FAFC`, slate `#334155`
|
||||
- print-ready, hoher Graustufenkontrast, großzügige Ränder
|
||||
- Labels: kurze **englische** Keywords (korrekt geschrieben)
|
||||
- Captions gehören **nicht** ins Bild (deutsch nur außerhalb)
|
||||
|
||||
**Nicht im Bild:** Vendor-Logos, Robotermaskottchen, Cyberpunk-Glow, Fake-UI-Screenshots, Watermarks, Prompt-Meta-Text als Labels, Wände aus Code.
|
||||
|
||||
## Ablauf (pro Abbildung)
|
||||
|
||||
### 1. Spec festziehen
|
||||
|
||||
Success-Kriterien als **prüfbare Checkliste** schreiben (5–12 Punkte), z. B.:
|
||||
|
||||
- [ ] Kernaussage visuell sofort lesbar
|
||||
- [ ] Alle Pflicht-Labels vorhanden und **korrekt buchstabiert**
|
||||
- [ ] Keine verbotenen Motive (Robots, Logos, …)
|
||||
- [ ] Layout: Landschaft 16:9, Ränder, kein Clipping
|
||||
- [ ] Stil: flat vector / Editorial, Palette stimmig
|
||||
- [ ] Keine erfundenen Extra-Labels / Meta-Text
|
||||
- [ ] (figur-spezifisch) …
|
||||
|
||||
Referenz-Checkliste: `references/qa-checklist.md`.
|
||||
|
||||
### 2. Prompt bauen
|
||||
|
||||
- Imagine-Prinzipien: Subject → Composition → Style → Lighting/Mood → Key details; 2–8 Sätze + klare Label-Liste.
|
||||
- **Hochauflösend / print-ready** explizit: sharp, high detail for print, clean edges, no compression artifacts.
|
||||
- Aspect: `image_gen` mit `aspect_ratio` (`16:9` Body, `2:3` Cover, …).
|
||||
- User-Prompt **verbatim**, wenn der User einen fertigen Prompt liefert.
|
||||
- Optional: Prompt-Datei unter `prompts/` anlegen/aktualisieren (nur wenn sinnvoll / beauftragt).
|
||||
|
||||
### 3. Generieren → Prüfen → (max. 5×) Wiederholen
|
||||
|
||||
```text
|
||||
attempt = 1
|
||||
MAX = 5
|
||||
|
||||
while attempt <= MAX:
|
||||
1) image_gen (oder image_edit bei gezielter Korrektur derselben Base)
|
||||
2) Ergebnis speichern / kanonischen Pfad setzen (s. §4)
|
||||
3) Bild mit read_file öffnen (multimodal) und gegen Spec-Checkliste prüfen
|
||||
4) if PASS → break
|
||||
5) if FAIL:
|
||||
- Mängel knapper Liste notieren
|
||||
- Entscheidung:
|
||||
a) leichte Korrektur / Stil-Hold → image_edit auf letztem Asset
|
||||
b) strukturell falsch / Text-Salat → neuer image_gen mit angepasstem Prompt
|
||||
c) exakte Struktur unrettbar → SVG-Pfad (Gate 0), Imagine-Loop beenden
|
||||
- attempt += 1
|
||||
```
|
||||
|
||||
**Harte Regeln im Loop**
|
||||
|
||||
- **Maximal 5** Imagine-Versuche (`image_gen` + `image_edit` zählen **gemeinsam** als Versuche).
|
||||
- Nach Fail: **eine** gezielte Änderung am Prompt/Edit — nicht den Prompt komplett neu erfinden ohne Bezug zu den Mängeln.
|
||||
- Garbled Text / erfundene Zahlen bei **exakter** Anforderung: nicht endlos re-prompten → Gate 0 (SVG/Code).
|
||||
- Moderations-/Safety-Block: **sofort stoppen**, nicht umformulieren zum Umgehen.
|
||||
- Parallel nur Varianten **desselben** Spec-Schritts, wenn sinnvoll; sonst sequentiell.
|
||||
|
||||
### 4. Speichern (Kanon)
|
||||
|
||||
| Stufe | Pfad |
|
||||
|-------|------|
|
||||
| Roh / Versuch | optional lokal `pics/` (gitignored) |
|
||||
| **Kanon** | `assets/illustrations/<ID>-<slug>.jpg` |
|
||||
| Cover | `assets/cover/cover-front.jpg` |
|
||||
| SVG-Quellen | `assets/illustrations/_gen/<ID>-….svg` → rasterisieren |
|
||||
|
||||
- Ziel: **JPEG**, print-tauglich (Projekt: quality ~85, wenn nachverarbeitet).
|
||||
- Wenn `image_gen` unter Session-Pfad speichert: Datei nach Kanon **kopieren/konvertieren** (`sips` / `magick` / `rsvg-convert` je nach Host).
|
||||
- Altes Kanon-Asset nur überschreiben, wenn User Regenerierung will; sonst Backup oder neuer Dateiname + Kapitel-Link-Update **nur mit Auftrag**.
|
||||
|
||||
### 5. QA-Report (immer)
|
||||
|
||||
```text
|
||||
## Abbildung: [ID] — [Kurztitel]
|
||||
**Datum:** [heute]
|
||||
**Versuche:** n / 5
|
||||
**Ergebnis:** PASS | FAIL | SVG-FALLBACK
|
||||
**Asset:** assets/illustrations/…
|
||||
|
||||
### Spec (Kern)
|
||||
- …
|
||||
|
||||
### Prüfung
|
||||
| Kriterium | OK? | Hinweis |
|
||||
|-----------|-----|---------|
|
||||
| … | ✅/❌ | … |
|
||||
|
||||
### Prompt-Anpassungen (pro Versuch)
|
||||
1. …
|
||||
2. …
|
||||
|
||||
### Nächste Schritte
|
||||
- [ ] Kapitel-Einbettung (nur mit Auftrag): `{width=90%}`
|
||||
- [ ] `abbildungen.md` Status aktualisieren (empfohlen)
|
||||
- [ ] Commit nur mit Auftrag
|
||||
```
|
||||
|
||||
### 6. Einbettung (nur mit Auftrag)
|
||||
|
||||
```markdown
|
||||
{width=90%}
|
||||
```
|
||||
|
||||
- Caption deutsch, endet mit Punkt wo üblich.
|
||||
- `{width=90%}` beibehalten.
|
||||
- `abbildungen.md` Inventar-Zeile auf **Asset da** / **Eingebettet** setzen.
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
| Vermeiden | Stattdessen |
|
||||
|-----------|-------------|
|
||||
| „Sieht gut aus“ ohne Checkliste | Multimodal gegen Spec-Punkte |
|
||||
| 5× derselbe Prompt | Fail-Ursache → gezielte Prompt-/Edit-Änderung |
|
||||
| Imagine für exakte Ring-/Zahlen-Diagramme bis zum Ende | SVG-first nach 1–2 Fails |
|
||||
| Vendor-Logos / Robots „für Wärme“ | Stil-Kanon |
|
||||
| Kapitel + 5 Figuren in einem Rutsch ohne Spec | Eine Figur, klare DoD |
|
||||
| Secrets / echte Hostnames im Prompt | Platzhalter |
|
||||
|
||||
## Slash / Aufruf
|
||||
|
||||
- `/abbildung` — Argument z. B. `F-01` oder freier Spec-Text
|
||||
- Chat: „Abbildung zur log-Dichte neu“, „Cover QA-Loop“
|
||||
|
||||
## Nicht tun
|
||||
|
||||
- `kladde.md` anfassen
|
||||
- PDF bauen, sofern nicht beauftragt
|
||||
- Gesamtrewrite von `abbildungen.md` oder Prompt-Baum „aus Prinzip“
|
||||
- Mehr als **5** Imagine-Versuche pro Figur und Lauf
|
||||
- Fail verschweigen und schwaches Asset als fertig melden
|
||||
@@ -0,0 +1,52 @@
|
||||
# QA-Checkliste — Buch-Abbildungen
|
||||
|
||||
Kurzreferenz für den Skill `abbildung`. Pro Figur: Spec-Punkte ausfüllen, dann multimodal prüfen (`read_file` auf dem Bild).
|
||||
|
||||
## Universal (immer)
|
||||
|
||||
| # | Kriterium | Fail-Hinweis |
|
||||
|---|-----------|--------------|
|
||||
| U1 | Kernaussage in ~3 s erfassbar | Komposition zu voll / Fokus unklar |
|
||||
| U2 | Pflicht-Labels vollständig | fehlende Keywords aus Spec |
|
||||
| U3 | Labels korrekt buchstabiert (EN) | Typos, Garbled Text, erfundene Wörter |
|
||||
| U4 | Keine verbotenen Motive | Robots, Vendor-Logos, Cyberpunk-Glow, Fake-UI, Watermarks |
|
||||
| U5 | Kein Prompt-Meta im Bild | „16:9“, „Create a…“, Qualitäts-Sätze als Text |
|
||||
| U6 | Stil: flat vector + soft depth, Editorial | Photoreal-Noise, Clipart-Chaos |
|
||||
| U7 | Palette stimmig (Navy/Teal/Blue/Off-white/Slate) | grelle Neon-Farben ohne Spec |
|
||||
| U8 | Ränder / kein Clipping | Text oder Formen am Rand abgeschnitten |
|
||||
| U9 | Aspect passend (Body 16:9, Cover oft 2:3) | falsches Format für Einsatz |
|
||||
| U10 | Drucktauglicher Kontrast (auch Graustufen) | hellgrau auf weiß, dünne Linien |
|
||||
|
||||
## Content-Genauigkeit (wenn Spec es verlangt)
|
||||
|
||||
| # | Kriterium | Fail → nächster Schritt |
|
||||
|---|-----------|-------------------------|
|
||||
| C1 | Feste Label-**Reihenfolge** stimmt | max. 1–2 Imagine-Retries, dann **SVG** |
|
||||
| C2 | Zahlen / Achsen / Zonen korrekt | nicht re-raten → Code/SVG |
|
||||
| C3 | Flussrichtung / Pfeile sinnvoll | gezieltes `image_edit` oder SVG |
|
||||
| C4 | Keine Extra-Labels außerhalb Spec | Prompt: „only these labels: …“ |
|
||||
| C5 | Hero-Title exakt (falls vorgeschrieben) | exakter String im Prompt wiederholen |
|
||||
|
||||
## Gate 0 — Abbruch Imagine → SVG
|
||||
|
||||
Nach **2** klaren Structural-Fails (C1–C3) nicht bis Versuch 5 leerlaufen:
|
||||
|
||||
1. Imagine-Loop beenden (Status: `SVG-FALLBACK` oder User-Frage).
|
||||
2. SVG unter `assets/illustrations/_gen/<ID>-….svg`.
|
||||
3. Raster: `rsvg-convert` (o. ä.) → `assets/illustrations/<ID>-….jpg`.
|
||||
|
||||
Historisch SVG-first: **M-09**, **S-03**, **K-12**.
|
||||
|
||||
## Versuch-Log (Kopiervorlage)
|
||||
|
||||
```text
|
||||
Versuch n/5 — Tool: image_gen | image_edit
|
||||
Asset: …
|
||||
FAIL: [U3, C1, …]
|
||||
Änderung nächstes Mal: …
|
||||
```
|
||||
|
||||
## Pass-Kriterium
|
||||
|
||||
**PASS** nur wenn alle Universal-Punkte U1–U10 und alle spezifizierten Content-Punkte grün sind.
|
||||
Teilweise „schön aber falsch“ = **FAIL**.
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
name: humanizer
|
||||
description: >
|
||||
Analysiert Text auf typische KI-Stilmuster und liefert begründete Vorher/Nachher-Vorschläge
|
||||
für eine menschlichere Stimme (Rhythmus, Floskeln, Epistemik, Spezifität). Keine automatischen Edits.
|
||||
Nutzen bei: „humanizer“, „menschlicher machen“, „KI-Stil entfernen“, „klingt zu generisch / roboterhaft“,
|
||||
„zu glatt formuliert“, „Floskeln raus“, /humanizer.
|
||||
when-to-use: >
|
||||
User will KI-Stil entfernen oder menschlicher formulieren. Manuskript-Kapitel
|
||||
(NN-*.md) oder Inline-Text. Nicht für Fakten-Lektorat oder Gegenlese.
|
||||
argument-hint: "01-einfuehrung.md"
|
||||
---
|
||||
|
||||
# Humanizer — KI-Stil → menschliche Stimme
|
||||
|
||||
Checkpoint-basierte Stilanalyse. **Report mit begründeten Vorschlägen**, keine stillen Textänderungen.
|
||||
|
||||
Referenzkatalog: `.commandcode/skills/humanizer/references/marker-katalog.md` (bei Bedarf mitlesen).
|
||||
|
||||
## Prinzipien
|
||||
|
||||
1. Zuerst lesen, dann urteilen — nicht nur Keyword-Scannen.
|
||||
2. Jeder Fund: **Muster + Warum + Vorher/Nachher**.
|
||||
3. Keine Detektor-Prozente, keine Urheber-Behauptung — nur editierbare Stilmerkmale.
|
||||
4. Keine künstlichen Tippfehler, kein Slang-Spam, kein Detektor-Gaming.
|
||||
5. Inhaltliche Fakten **nicht erfinden**, um „spezifischer“ zu klingen.
|
||||
6. Standard: nur Chat-Report. Edits **nur** auf explizite Freigabe, chirurgisch.
|
||||
|
||||
### Leitprinzipien der Humanisierung
|
||||
|
||||
| # | Prinzip | Wirkung |
|
||||
|---|---------|---------|
|
||||
| 1 | Rhythmus variieren (Burstiness) | Kurze und lange Sätze mischen; Absätze ungleich gewichten |
|
||||
| 2 | Floskeln und Werbelexik streichen | Konkrete Wörter statt Buzz |
|
||||
| 3 | Spezifität | Szenen, Commands, Zahlen, echte Tradeoffs statt Prototypen |
|
||||
| 4 | Epistemische Ehrlichkeit | Grenzen, Unsicherheit, echte Einwände |
|
||||
| 5 | Asymmetrie | Wichtiges länger, Nebensächliches knapper |
|
||||
| 6 | Stimme | Aktiver Kollege, nicht Pressemitteilung |
|
||||
|
||||
### Was „menschlicher“ *nicht* heißt
|
||||
|
||||
- Nicht: salopp um jeden Preis oder „natürlich“ = umgangssprachlich.
|
||||
- Nicht: Buch-Ton brechen (bei Manuskript: verlässlicher Erklärer — präzise, geduldig, ohne Hype — `schreibkonventionen.md`).
|
||||
- Nicht: verbindliche Kapitel-Abschlüsse umbenennen (Labels laut `00-inhaltsverzeichnis.md`).
|
||||
- Stark redigierte Fachprosa teilt oft niedrige Burstiness mit KI — **Stimme und Nutzen** priorisieren, nicht „detektor-unsichtbar“.
|
||||
|
||||
## Abgrenzung
|
||||
|
||||
| Skill | Fokus |
|
||||
|-------|--------|
|
||||
| `lektorat` | Ton, Fakten, Terminologie, Wiederholungen, Erklärungsdichte, Struktur |
|
||||
| `kapitel-review` | Argumentation, Lesefluss, Substanz, Positionierung |
|
||||
| **`humanizer`** | KI-typische Stilmarker → menschliche Stimme |
|
||||
|
||||
Humanizer ersetzt weder Fakten-Check noch Argumentations-Review. Bei Konflikt mit Buch-Konventionen gewinnt `schreibkonventionen.md` / `AGENTS.md`.
|
||||
|
||||
## Vorbereitung
|
||||
|
||||
1. **Input klären:** Kapitel (`NN-*.md` / Dateiname), markierter Abschnitt, oder Inline-Text. Bei Unklarheit nachfragen.
|
||||
2. **Zielstimme** (Default):
|
||||
- Manuskript / Buch-Kontext → **Verlässlicher Erklärer** (präzise, geduldig, kein Hype, keine Sensationsgier)
|
||||
- Sonst → **Sachprosa DE** (klar, konkret, ohne Werbeton)
|
||||
3. Text **vollständig** lesen (Datei: `read_file`). Bei sehr langen Kapiteln: mit User abschnittsweise oder Fokus-Abschnitt wählen.
|
||||
4. Marker-Katalog bei Bedarf öffnen: `references/marker-katalog.md`.
|
||||
|
||||
## Checkpoints (der Reihe nach)
|
||||
|
||||
### 1. Lexik & Floskeln
|
||||
|
||||
- Buzz-Adjektive, Superlative ohne Beleg, Stereotype Verben (siehe Katalog HIGH/MED)
|
||||
- Co-Occurrence: mehrere Marker nahe beieinander = stärkeres Signal als ein einzelnes Wort
|
||||
- Nominalisierungs-Stapel und Partizipialketten, die den Satz aufblähen
|
||||
|
||||
→ Jeden Treffer mit Vorschlag konkretisieren oder streichen.
|
||||
|
||||
### 2. Übergänge & Meta-Rhetorik
|
||||
|
||||
- Absatzanfänge: „Darüber hinaus“, „Ferner“, „Zudem“, „Ein weiterer wichtiger Aspekt …“
|
||||
- Ankündigungen ohne Nutzen: „Im Folgenden wird …“, „Es ist wichtig zu betonen …“
|
||||
- Mechanische Parallelismen und immer gleiche Konnektoren
|
||||
|
||||
→ Übergang streichen, implizit machen oder mit Inhalt ersetzen.
|
||||
|
||||
### 3. Rhythmus (Burstiness)
|
||||
|
||||
- Satzlängen über 5–10 Sätze hinweg: monoton ≈ KI-Nähe
|
||||
- Absätze alle ~gleich lang
|
||||
- Listen statt Prosa, wo ein Satz reichte — oder umgekehrt: Prosa-Wand ohne Atem
|
||||
|
||||
→ Mindestens 1–2 Vorher/Nachher mit bewusster Längen-Varianz vorschlagen.
|
||||
|
||||
### 4. Struktur-Symmetrie
|
||||
|
||||
- Gleich gewichtete Unterabschnitte („drei Punkte à drei Sätze“)
|
||||
- Tricolon-Zwang (immer genau drei Aufzählungen)
|
||||
- Ungebetene Mini-Fazits am Ende jedes Blocks („Zusammenfassend …“)
|
||||
|
||||
→ Asymmetrie vorschlagen: Kern länger, Rest kürzen oder streichen.
|
||||
|
||||
### 5. Epistemik & Stimme
|
||||
|
||||
- Phantom-Autorität: „Studien zeigen“, „Experten sind sich einig“ ohne Name/Quelle
|
||||
- Pauschale Sicherheit ohne Bedingungen; oder leeres Hedging überall
|
||||
- Keine echten Zugeständnisse / Tradeoffs
|
||||
- Pressemitteilungs-Ton statt Kollege mit Position
|
||||
|
||||
→ Grenzen, „wann gilt das nicht“, konkrete Alternativen — ohne Fakten zu erfinden.
|
||||
|
||||
### 6. Spezifität
|
||||
|
||||
- Generische Beispiele (Café-WLAN, „die App“, „das Team“)
|
||||
- Abstrakte Nutzen-Sätze ohne greifbaren Nachvollzieh-Schritt
|
||||
- Im Buch-Kontext: fehlt ein Rechenbeispiel-/Figur-/Quellen-Anker, wo er hingehört?
|
||||
|
||||
→ Spezifischer vorschlagen **nur** aus Kontext des Textes oder der Forschungsbasis (`docs/`, Kapitel-Szenen); sonst markieren „braucht Autor-Detail“.
|
||||
|
||||
### 7. Buch-Guardrails (nur Manuskript)
|
||||
|
||||
- Verbindliche Abschluss-Labels (laut `00-inhaltsverzeichnis.md`) und sinnvolle Blockquote-Struktur intakt lassen
|
||||
- Terminologie-Collatz-Kanon einheitlich (`.commandcode/rules/schreibkonventionen.md` § Terminologie)
|
||||
- Keine erfundenen Zahlen/Namen; Faktenschutz bleibt
|
||||
- Vorschläge dürfen den Ton „verlässlicher Erklärer“ nicht in Marketing, Belehrung oder Sensation kippen
|
||||
- „Ungelöst bleibt ungelöst“ — keine Scheinlösungs-Rhetorik einführen
|
||||
|
||||
## Ausgabeformat
|
||||
|
||||
```text
|
||||
## Humanizer: [Quelle]
|
||||
**Datum:** [heute]
|
||||
**Zielstimme:** [Verlässlicher Erklärer | Sachprosa | …]
|
||||
**Scope:** [z. B. ganzes Kapitel / Abschnitte X–Y / ~N Absätze]
|
||||
|
||||
### Gesamteindruck (2–4 Sätze)
|
||||
KI-Nähe grob: niedrig | mittel | hoch — Begründung (Muster, nicht Prozent).
|
||||
|
||||
### Funde (priorisiert)
|
||||
|
||||
**P0 — stark KI-typisch / stört Lesbarkeit:**
|
||||
- **Stelle:** „…“ (Kontext: …)
|
||||
- **Muster:** [Lexik | Übergang | Rhythmus | Struktur | Epistemik | Spezifität]
|
||||
- **Warum:** …
|
||||
- **Vorschlag:**
|
||||
- Vorher: …
|
||||
- Nachher: …
|
||||
- **Nebenwirkung:** [optional]
|
||||
|
||||
**P1 — sollte:**
|
||||
…
|
||||
|
||||
**P2 — Feinschliff:**
|
||||
…
|
||||
|
||||
### Muster-Statistik (kurz)
|
||||
- Floskeln / Übergänge: N | Rhythmus: … | Epistemik: … | Struktur: … | Spezifität: …
|
||||
|
||||
### Top-3 Sofortmaßnahmen
|
||||
1. …
|
||||
2. …
|
||||
3. …
|
||||
```
|
||||
|
||||
### Priorisierung & Menge
|
||||
|
||||
- **P0:** max. ~8 Einzelvorschläge; wiederkehrende Muster als „Muster X tritt N-mal auf“ + 1–2 exemplarische Rewrites
|
||||
- **P1/P2:** Rest; kein romanlanger Fundkatalog
|
||||
- Jeder P0/P1-Eintrag braucht Vorher/Nachher (außer bei reinem Streichen: Nachher = leer / Hinweis „streichen“)
|
||||
|
||||
## Nach dem Lauf
|
||||
|
||||
- Standard: Report in der Chat-Antwort; Datei nur auf Wunsch.
|
||||
- **Nur freigegebene** Funde umsetzen; keine Drive-by-Edits.
|
||||
- Bei „setz alles um“: trotzdem Checkpoint für riskante Stellen (Inhalt, Abschlüsse, Fakten).
|
||||
- Optional: User fragen, ob danach `lektorat` oder `kapitel-review` sinnvoll ist.
|
||||
|
||||
## Anti-Patterns (Agent)
|
||||
|
||||
- Ganzen Text in einem Rutsch umschreiben ohne Scope
|
||||
- „Humanizer-Slang“ (übertriebene Umgangssprache, Memes)
|
||||
- Fakten, Quellen oder Config-Flags erfinden
|
||||
- Kapitel-Abschluss-Labels „verschönern“ oder umbenennen
|
||||
- Detektor-Scores oder „das ist 87 % KI“ behaupten
|
||||
@@ -0,0 +1,177 @@
|
||||
# Marker-Katalog — KI-Stil vs. menschliche Stimme
|
||||
|
||||
Nachschlagewerk für den Skill `humanizer`. Stand der Stilforschung/Praxis: 2025/2026.
|
||||
**Kein** Detektor und **kein** Urheber-Beweis — nur editierbare Muster.
|
||||
|
||||
Schwere:
|
||||
|
||||
| Stufe | Bedeutung |
|
||||
|-------|-----------|
|
||||
| **HIGH** | Oft Co-Occurrence-Signal; bei Häufung prioritär (P0) |
|
||||
| **MED** | Unauffällig allein; problematisch in Clustern oder am Absatzanfang |
|
||||
| **LOW** | Nur bei Monotonie/Übernutzung melden |
|
||||
|
||||
---
|
||||
|
||||
## 1. Deutsch — Konnektoren & Meta-Rhetorik
|
||||
|
||||
| Marker / Muster | Schwere | Gegenmittel |
|
||||
|-----------------|---------|-------------|
|
||||
| Darüber hinaus / Ferner / Zudem (Absatzanfang) | HIGH | Streichen; Inhalt direkt; „Außerdem“ sparsam |
|
||||
| Ein weiterer wichtiger Aspekt ist … | HIGH | Aspekt nennen und erklären, Ankündigung weg |
|
||||
| Es ist wichtig zu betonen / festzuhalten … | HIGH | Behauptung + Begründung, ohne Meta |
|
||||
| Im Folgenden wird … / Nachfolgend betrachten wir … | HIGH | Direkt starten |
|
||||
| Zusammenfassend lässt sich sagen / Insgesamt zeigt sich | HIGH | Fazit nur am Kapitelende oder weglassen |
|
||||
| Nicht nur … sondern auch … (seriell) | MED | Eine Aussage genügt oft |
|
||||
| Insbesondere / Grundsätzlich / Letztendlich / Zweifellos | MED | Konkretisieren oder streichen |
|
||||
| In diesem Zusammenhang / Vor diesem Hintergrund | MED | Bezug im Satz selbst herstellen |
|
||||
|
||||
### Vorher → Nachher
|
||||
|
||||
```text
|
||||
Vorher: Darüber hinaus ist es von entscheidender Bedeutung, innovative Lösungen
|
||||
nahtlos zu implementieren.
|
||||
Nachher: Neue Lösungen müssen ohne Extra-Reibung in den bestehenden Ablauf passen.
|
||||
|
||||
Vorher: Im Folgenden wird erläutert, wie Permissions greifen.
|
||||
Nachher: Permissions greifen so:
|
||||
|
||||
Vorher: Zusammenfassend lässt sich sagen, dass ein enger Scope Risiken senkt.
|
||||
Nachher: Enger Scope senkt Risiken — das war der Punkt.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Deutsch — Buzz-Lexik & Werbeton
|
||||
|
||||
| Marker | Schwere | Gegenmittel |
|
||||
|--------|---------|-------------|
|
||||
| nahtlos, ganzheitlich, maßgeschneidert | HIGH | Was genau passiert / fehlt? |
|
||||
| zukunftsorientiert, bahnbrechend, beispiellos | HIGH | Streichen oder mit Beleg ersetzen |
|
||||
| innovativ, dynamisch, robust, skalierbar (ohne Kontext) | MED | Technische Konkretion |
|
||||
| facettenreich, essenziell, hochwertig, effizient | MED | Warum / für wen? |
|
||||
| Paradigmenwechsel, Gamechanger, Best Practice | HIGH | Sachverhalt benennen |
|
||||
| nutzen / nutzen Sie die Kraft von … | MED | Verb mit Objekt: was *tut* man? |
|
||||
|
||||
```text
|
||||
Vorher: Eine ganzheitliche, maßgeschneiderte Strategie ermöglicht nahtlose Workflows.
|
||||
Nachher: Eine kurze Deny-Liste und ein enger Working-Directory-Scope reichen oft,
|
||||
um destruktive Tool-Calls abzufangen.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Epistemik & leere Autorität
|
||||
|
||||
| Muster | Schwere | Gegenmittel |
|
||||
|--------|---------|-------------|
|
||||
| Studien zeigen / Forschung belegt (ohne Quelle) | HIGH | Quelle nennen oder Behauptung abschwächen/streichen |
|
||||
| Experten sind sich einig … | HIGH | Wer? Sonst streichen |
|
||||
| Es ist klar, dass / Zweifellos | MED | Bedingungen nennen |
|
||||
| Immer / nie / jeder / optimal (Absolutismen) | MED | Scope der Aussage eingrenzen |
|
||||
| Kein Tradeoff, kein „wann gilt das nicht“ | MED | Einen echten Einwand einbauen |
|
||||
| Leeres Hedging überall („könnte ggf. möglicherweise“) | MED | Entweder klar oder mit konkreter Unsicherheit |
|
||||
|
||||
```text
|
||||
Vorher: Studien zeigen, dass gut strukturierte Prompts die Qualität deutlich steigern.
|
||||
Nachher: In der Praxis steigt die Trefferquote, wenn Scope und Erfolgskriterien
|
||||
im Prompt stehen — messbar z. B. an weniger Nachfragen pro Task.
|
||||
(Ohne Studie: als Erfahrung markieren, nicht als „Studien“.)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Rhythmus (Burstiness) & Syntax
|
||||
|
||||
| Muster | Schwere | Gegenmittel |
|
||||
|--------|---------|-------------|
|
||||
| Sätze fast gleicher Länge über längere Strecke | HIGH | Kurz / lang / Fragment mischen |
|
||||
| Absätze alle 3–4 Sätze, gleiche Form | HIGH | Asymmetrie: ein Block 1 Satz, einer 6 |
|
||||
| Partizipialketten („…, nutzend …, basierend auf …“) | MED | Hauptsätze; Verben aktiv |
|
||||
| Nominalisierungs-Stapel (die Implementierung der …) | MED | Tun-Wörter: „du setzt …“, „der Hook prüft …“ |
|
||||
| Immer vollständige, glatte Sätze — nie Ellipsen | LOW | Gelegentlich erlaubt: „Kurz:“ / „Der Haken:“ |
|
||||
| Listen für alles | MED | Prosa, wenn 1–2 Punkte reichen |
|
||||
|
||||
### Rhythmus-Test (30 Sekunden)
|
||||
|
||||
Drei aufeinanderfolgende Sätze laut lesen. Klingt es wie Metronom?
|
||||
Wenn ja: einen Satz halbieren, einen verdoppeln, einen zum Ein-Satz-Absatz machen.
|
||||
|
||||
```text
|
||||
Vorher: Permissions steuern den Tool-Zugriff. Sie bestehen aus Allow- und Deny-Regeln.
|
||||
Deny greift vor Allow. Das verhindert riskante Defaults.
|
||||
|
||||
Nachher: Permissions steuern, welche Tools der Agent überhaupt ausführen darf.
|
||||
Deny vor Allow — sonst gewinnt die breite Freigabe.
|
||||
Das ist der häufigste Konfigurationsfehler.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Struktur
|
||||
|
||||
| Muster | Schwere | Gegenmittel |
|
||||
|--------|---------|-------------|
|
||||
| Tricolon-Zwang (immer drei Aufzählungen) | MED | 2 oder 4, wenn es passt; oder Prosa |
|
||||
| Drei gleich lange Unterabschnitte à Schema | HIGH | Kernabschnitt länger; Rest kürzen |
|
||||
| Jeder Abschnitt endet mit Mini-Fazit | HIGH | Fazit nur wo Transfer nötig |
|
||||
| Einleitung spiegelt Schluss 1:1 | MED | Schluss = nächster Schritt, nicht Echo |
|
||||
| Perfekte Parallelismen in jedem Bullet | LOW | Variation der Bullet-Form |
|
||||
|
||||
---
|
||||
|
||||
## 6. Spezifität vs. Generik
|
||||
|
||||
| Muster | Schwere | Gegenmittel |
|
||||
|--------|---------|-------------|
|
||||
| Prototyp-Beispiele (Café-WLAN, „die App“, „das Unternehmen“) | MED | Repo-/Alltagsbeispiel des Lesers |
|
||||
| Nutzen ohne Mechanik („verbessert die Effizienz“) | HIGH | Wie + woran merkst du es? |
|
||||
| Fehlende Szene vor Lookup-Tabelle (Buch) | MED | 1–2 Sätze Leserproblem davor |
|
||||
| Abstrakte „Teams profitieren von …“ | MED | Eine konkrete Situation |
|
||||
|
||||
```text
|
||||
Vorher: Teams profitieren von klaren Richtlinien und einer robusten Tool-Policy.
|
||||
Nachher: Freitag 17 Uhr, Hotfix-Branch: ohne Deny auf `rm` und ohne enges Working
|
||||
Directory ist ein „aufräumen“-Prompt ein Produktionsrisiko.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Englische Parallel-Marker (kurz)
|
||||
|
||||
Nur bei EN- oder Mischtext. Co-Occurrence zählt mehr als Einzelwort.
|
||||
|
||||
| EN-Marker | Schwere | DE-Nähe / Ersatz |
|
||||
|-----------|---------|------------------|
|
||||
| furthermore / moreover / additionally | HIGH | also / and / streichen |
|
||||
| it is worth noting / it is important to | HIGH | point first |
|
||||
| in conclusion / to summarize / in essence | HIGH | so / the upshot |
|
||||
| delve / leverage / navigate / utilize | HIGH | examine / use / handle |
|
||||
| seamlessly / cutting-edge / transformative / multifaceted | HIGH | concrete verb/noun |
|
||||
| studies show / experts agree (unnamed) | HIGH | name source or drop |
|
||||
| nestled / tapestry / realm / landscape (metaphor clutter) | MED | plain language |
|
||||
|
||||
---
|
||||
|
||||
## 8. Schnell-Checkliste vor dem Report
|
||||
|
||||
- [ ] HIGH-Marker gezählt (Cluster = P0)?
|
||||
- [ ] Mindestens ein Rhythmus-Vorschlag mit Längenvarianz?
|
||||
- [ ] Epistemik: Phantom-Autorität oder fehlende Grenzen markiert?
|
||||
- [ ] Spezifität: Vorschläge ohne erfundene Fakten?
|
||||
- [ ] Manuskript: Callouts und Terminologie unangetastet?
|
||||
- [ ] P0 ≤ ~8; Wiederholmuster aggregiert?
|
||||
|
||||
---
|
||||
|
||||
## 9. Falsch-Positive (nicht überkorrigieren)
|
||||
|
||||
Diese Merkmale allein machen Text **nicht** „KI“:
|
||||
|
||||
- Fachtermini und enge Genre-Konventionen (API-Docs, Methodenabschnitte)
|
||||
- Kurze, klare Sätze (Buch-Stil: erwünscht)
|
||||
- Eine einzelne Konjunktion „zudem“ mitten im Fließtext
|
||||
- Listen in Checklisten/Katalog-Kapiteln und echten Lookup-Rastern
|
||||
- Einheitliche Terminologie (Collatz-Kanon) — das ist Konsistenz, kein Template-Zwang
|
||||
|
||||
**Regel:** Nur eingreifen, wenn Muster **häufen**, den **Lesefluss** stören oder die **Stimme** zur Pressemitteilung machen.
|
||||
@@ -0,0 +1,95 @@
|
||||
---
|
||||
name: kapitel-review
|
||||
description: >
|
||||
Kritische Gegenlese eines oder mehrerer Kapitel des Sachbuchs „Die Collatz-Vermutung“ —
|
||||
Argumentation, Lesefluss, Substanz, Ton. Kein volles Lektorat, keine automatischen Edits.
|
||||
Nutzen bei: „Review Kapitel 4“, „Gegenlese Kap. 8“, „Feedback zur Einführung“, /gegenlese.
|
||||
when-to-use: >
|
||||
User will Gegenlese oder argumentatives Feedback zu Manuskript-Kapiteln.
|
||||
Nicht für Checkpoint-Lektorat (lektorat), nicht für KI-Stil allein (humanizer).
|
||||
argument-hint: "01-einfuehrung.md"
|
||||
---
|
||||
|
||||
# Kapitel-Review-Skill — Die Collatz-Vermutung
|
||||
|
||||
Strukturierte Gegenlese. Feedback, keine stillen Manuskript-Änderungen.
|
||||
|
||||
## Prinzipien
|
||||
|
||||
1. Erst ganz lesen, dann urteilen.
|
||||
2. Nur substanzielle Funde — keine Geschmacksfragen.
|
||||
3. Keine eigenen Edits, außer der User fordert Umsetzung.
|
||||
4. Fertig, wenn alle vier Dimensionen abgedeckt sind.
|
||||
|
||||
## Vorbereitung
|
||||
|
||||
1. Kapitel klären (Dateiname oder Nummer).
|
||||
2. Vollständig lesen.
|
||||
3. Nachbarkapitel und ggf. README-Lesepfade kurz überfliegen (Wiederholungen, Brüche, Bogen).
|
||||
|
||||
## Dimensionen
|
||||
|
||||
### 1. Argumentation & roter Faden
|
||||
|
||||
- Ist der Kern des Kapitels klar (Einstiegsfrage / These)?
|
||||
- Baut die Argumentation logisch auf (Frage → Beobachtung → Mechanik → Bedeutung → offener Rest)?
|
||||
- Behauptungen mit Beispiel, Heuristik oder Quelle — ohne Mystifikation?
|
||||
- Passt es in den Bogen: Vermutung → Werkzeugkasten → was bewiesen ist → was gerechnet wird → warum es offen bleibt?
|
||||
|
||||
### 2. Lesefluss & Verständlichkeit
|
||||
|
||||
- Einladender Einstieg?
|
||||
- Übergänge zwischen Abschnitten?
|
||||
- Laien-tauglich: Stolperstellen, vorausgesetzte Vorbildung, unpassende Fachsprache?
|
||||
- Formeln aufgelöst, Beispiele vor Theorie?
|
||||
- Verbindliche Abschlüsse (laut `00-inhaltsverzeichnis.md`) wirksam?
|
||||
|
||||
### 3. Substanz & Tiefe
|
||||
|
||||
- Angemessene Tiefe (weder oberflächlich noch überladen)?
|
||||
- Mathematik korrekt und mit `docs/`-Bezug; Grenzen/Rekorde in der verbürgten Formulierung?
|
||||
- Zu viele Exkurse?
|
||||
- Heuristik ≠ Beweis klar getrennt?
|
||||
- „Ungelöst bleibt ungelöst“ — kippt die Erzählung irgendwo in Scheinlösung oder Fatalismus?
|
||||
|
||||
### 4. Ton & Positionierung
|
||||
|
||||
- Verlässlicher Erklärer, neugierig statt sensationslüstern?
|
||||
- Risiken und Unwissen ehrlich benannt, ohne Panik?
|
||||
- Stellen arrogant, belehrend oder zu salopp?
|
||||
- Kein Hype, keine „gelöst!“-Framings?
|
||||
|
||||
## Ausgabeformat
|
||||
|
||||
```text
|
||||
## Review: [Kapitel]
|
||||
**Datum:** [heute]
|
||||
**Typ:** Gegenlese (kein Lektorat)
|
||||
|
||||
### Gesamteindruck (2–3 Sätze)
|
||||
|
||||
### Stärken
|
||||
- …
|
||||
|
||||
### Schwächen (priorisiert)
|
||||
**P0 — behindert Verständnis:**
|
||||
- …
|
||||
|
||||
**P1 — schwächt das Kapitel:**
|
||||
- …
|
||||
|
||||
**P2 — nice-to-have:**
|
||||
- …
|
||||
|
||||
### Im Verhältnis zum Gesamtbuch
|
||||
- Wiederholungen / Widersprüche / fehlende Brücken
|
||||
|
||||
### Empfehlung
|
||||
- Bereit fürs Lektorat | Überarbeiten mit Fokus auf X | Grundlegend umbauen: Y
|
||||
```
|
||||
|
||||
## Nach der Review
|
||||
|
||||
- Standard: nur Chat-Antwort.
|
||||
- Review-Datei nur auf Wunsch.
|
||||
- Keine automatische Umsetzung der Vorschläge.
|
||||
@@ -0,0 +1,109 @@
|
||||
---
|
||||
name: lektorat
|
||||
description: >
|
||||
Strukturierter Lektorats-Durchlauf für Kapitel des Sachbuchs „Die Collatz-Vermutung“.
|
||||
Ton, Fakten, Terminologie, Wiederholungen, Erklärungsdichte, Struktur.
|
||||
Nutzen bei: „Lektorier Kapitel 3“, „Lektorat 04–05“, „Prüfe den Ton in Kapitel 9“, /lektorat.
|
||||
when-to-use: >
|
||||
User will Lektorat oder stilistisch-terminologische Prüfung eines oder mehrerer
|
||||
Manuskript-Kapitel. Nicht für Gegenlese (kapitel-review), nicht für KI-Stil allein
|
||||
(humanizer), nicht für buchweite Vollprüfung (total-check).
|
||||
argument-hint: "01-einfuehrung.md"
|
||||
---
|
||||
|
||||
# Lektorats-Skill — Die Collatz-Vermutung
|
||||
|
||||
Checkpoint-basiertes Lektorat. Prinzipien: `AGENTS.md`. Schreibregeln: `.commandcode/rules/schreibkonventionen.md`. Wärme-Bausteine (Lesbarkeit): `.commandcode/skills/lektorat/references/waerme.md` — bei Kapitelprosa mitladen.
|
||||
|
||||
## Vorbereitung
|
||||
|
||||
1. Welche Kapitel? Dateinamen `NN-*.md` im Root (ohne `00-inhaltsverzeichnis.md`), oder Nummern; bei Unklarheit nachfragen.
|
||||
2. Kapitel mit `read_file` lesen (nicht nur scannen).
|
||||
3. Bei mathematischen Fakten (Grenzen, Rekorde, Theoreme, Jahreszahlen): nicht raten — gegen `docs/` (Forschungsbasis) prüfen; Unsicherheit markieren.
|
||||
4. Faktenschutz beachten: „ungelöst bleibt ungelöst“; Formulierungen für Grenzen/Rekorde stammen aus `docs/`.
|
||||
|
||||
## Checkpoints (der Reihe nach)
|
||||
|
||||
### 1. Ton
|
||||
|
||||
- Verlässlicher Erklärer: präzise, geduldig, ehrlich, ohne Hype?
|
||||
- Sensations-Floskeln, „gelöst!“-Framings, Genie-Kitsch?
|
||||
- Offene Fragen ehrlich offengelassen — kein Scheinabschluss?
|
||||
- Funde mit Kontext (Überschrift / Zitat) dokumentieren.
|
||||
|
||||
→ Jede Ton-Abweichung: konkreter Änderungsvorschlag.
|
||||
|
||||
### 2. Fakten und Faktenschutz
|
||||
|
||||
- Alle mathematischen Aussagen gegen `docs/0*.md` geprüft (Autor+Jahr-Zitat im Text)?
|
||||
- Stand-Angaben (Verifikationsgrenze `2^71`, Tao-Satz, Zyklen-Grenzen `m ≤ 91`, Undecidability der *Generalisierung*) nur in der `docs/`-Formulierung?
|
||||
- Zahlen mit Kontext (Größenordnung vermittelt)?
|
||||
- Keine erfundenen Namen, Zitate, Studien, Daten?
|
||||
- Widersprüche zu anderen Kapiteln oder zu `docs/`?
|
||||
|
||||
→ Unbelegte oder riskante Behauptungen markieren; Korrektur-Loop erst `docs/`, dann Manuskript.
|
||||
|
||||
### 3. Terminologie
|
||||
|
||||
- Collatz-Kanon einheitlich (Tabelle in `.commandcode/rules/schreibkonventionen.md`)?
|
||||
- Stoppzeit ≠ Gesamtstoppzeit, Shortcut-Map benannt, log-Dichte ≠ natürliche Dichte, Verifikation ≠ Beweis?
|
||||
- Jeder Fachbegriff beim Erstauftreten im Kapitel erklärt?
|
||||
- Namen und Fachbegriffe original (Collatz, Erdős, Lagarias, Tao; *stopping time* mit Übersetzung)?
|
||||
|
||||
→ Varianten innerhalb eines Kapitels auflisten.
|
||||
|
||||
### 4. Wiederholungen
|
||||
|
||||
- Gleiche Erklärung mehrfach ohne Mehrwert?
|
||||
- Sinnvolle Rekapitulation vs. Redundanz (max. 2–3 Reprise-Signale pro Kapitel)?
|
||||
- Brücken zu Nachbarkapiteln prüfen (kurz überfliegen).
|
||||
|
||||
→ Vorschlag: streichen / kürzen / verweisen.
|
||||
|
||||
### 5. Erklärungsdichte (Wie & Warum)
|
||||
|
||||
- Formeln sparsam und umgangssprachlich aufgelöst; Rechenbeispiel vor Formel?
|
||||
- Analogien als Vergleichshilfe markiert („Bild, kein Beweis“)?
|
||||
- Pro lehrendem `###` Wie + Warum erkennbar?
|
||||
- Szene/Alltagsbeispiel vor Theorie, wo machbar?
|
||||
|
||||
### 6. Lesbarkeit und Struktur
|
||||
|
||||
- Verbindliche Abschluss-Labels (laut `00-inhaltsverzeichnis.md`) vorhanden und wirksam?
|
||||
- Satellite-`##` mit `{.unnumbered .unlisted}`?
|
||||
- Laien-Tauglichkeit: Stolperstellen (Sätze, die Vorbildung voraussetzen)?
|
||||
- Links zu `docs/`-Quellen intakt?
|
||||
|
||||
### 7. Hygiene in Beispielen
|
||||
|
||||
- Keine erfundenen Rechenwerte oder „ist leicht zu prüfen“-Behauptungen ohne eigene Prüfung?
|
||||
- `kladde.md` und Meta-Dateien nicht fälschlich als Buchkapitel behandelt?
|
||||
- Keine ungefragten Exkurse hineingerutscht?
|
||||
|
||||
## Ausgabeformat
|
||||
|
||||
```text
|
||||
## Lektorat: [Kapitel]
|
||||
**Datum:** [heute]
|
||||
**Checkpoints:** 1–7
|
||||
|
||||
### Funde (priorisiert)
|
||||
**P0 (muss):**
|
||||
- …
|
||||
|
||||
**P1 (sollte):**
|
||||
- …
|
||||
|
||||
**P2 (kann):**
|
||||
- …
|
||||
|
||||
### Statistik
|
||||
- Ton / Fakten / Terminologie / Wiederholungen / Erklärungsdichte / Struktur / Hygiene: N jeweils
|
||||
```
|
||||
|
||||
## Nach dem Durchlauf
|
||||
|
||||
- Standard: Report in der Chat-Antwort; Datei nur auf expliziten Wunsch.
|
||||
- **Nur freigegebene** Änderungen ins Manuskript einarbeiten.
|
||||
- Keine Drive-by-Edits außerhalb der Funde.
|
||||
- Kein Gesamtrewrite des Buchs.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Wärme-Bausteine — Lesbarkeit (Lektorat)
|
||||
|
||||
On demand beim Lektorat / Kapitelprosa. Always-on bleiben Ton, Terminologie und Abschlüsse in `.commandcode/rules/schreibkonventionen.md`.
|
||||
|
||||
Menschlicher Ton **ohne** Hype und ohne Slang. Bausteine für Laien-Sachbuchprosa (Szene vor Erklärung, Atem, Katalog-Einstieg, Brücke, Asymmetrie):
|
||||
|
||||
| Baustein | Was er leistet | Nicht so |
|
||||
|----------|----------------|----------|
|
||||
| **Szene vor Lookup** | 1–3 Sätze Leserproblem *vor* großer Tabelle | Essay-Einstieg oder Szene *statt* Inhalt |
|
||||
| **Atem holen** | Dichte Absätze in 2–3 kurze Züge; Punchline nach vorn | Rhythmisch monotones These→Tabelle→Do/Avoid |
|
||||
| **Katalog-Einstieg** | Ein Satz, warum die Liste jetzt kommt | Katalog-Zeilen zu Mini-Essays aufblasen |
|
||||
| **Brücke knapper** | Verweis + *neuer* Aspekt | Kapitel-Echo ohne Mehrwert |
|
||||
| **Asymmetrie** | Ein greifbares Beispiel schlägt drei generische | „in modernen Teams oft …“ ohne Szene |
|
||||
|
||||
**Reihenfolge der Hebel:** Prosa/Pacing vor neuen Figuren. Figuren nur bei mentalem Modell mit stabilem Label-Bedarf; exakte Diagramme **SVG-first**.
|
||||
@@ -0,0 +1,85 @@
|
||||
---
|
||||
name: pdf-bauen
|
||||
description: >
|
||||
Baut das PDF „Die Collatz-Vermutung“ über die just-Pipeline und führt QA aus.
|
||||
Behebt Build-Fehler und interpretiert QA. Nutzen bei: „Bau das PDF“, „PDF generieren“,
|
||||
„Draft bauen“, „QA-Check“, „Warum schlägt der Build fehl?“, /pdf.
|
||||
when-to-use: >
|
||||
User will eBook-PDF bauen, assemblieren oder QA. Nicht für Print/KDP (pdf-print).
|
||||
Nur bei explizitem Auftrag ausführen.
|
||||
argument-hint: "[full|draft|plain]"
|
||||
---
|
||||
|
||||
# PDF-Bau-Skill — Die Collatz-Vermutung
|
||||
|
||||
Pipeline: Assembler → Pandoc → LuaLaTeX → QA. Details (nur bei Build-Task laden): `.commandcode/skills/pdf-bauen/references/pipeline.md`.
|
||||
|
||||
## Prinzipien
|
||||
|
||||
1. Denken vor dem Schreiben — Fehler analysieren, bevor blind neu gebaut wird.
|
||||
2. Einfachheit — nur die Build-Art, die nötig ist.
|
||||
3. Chirurgisch — während des Bauens keine Manuskript-Edits „nebenbei“.
|
||||
4. Zielgetrieben — fertig erst, wenn der verlangte Build (und bei full: QA) steht.
|
||||
|
||||
## Build-Arten
|
||||
|
||||
| Art | Kommando | Output |
|
||||
|-----|----------|--------|
|
||||
| full (default) | `just pdf` | `dist/collatz-vermutung.pdf` (A4 eBook) |
|
||||
| draft | `just pdf-draft` | `dist/collatz-vermutung-draft.pdf` |
|
||||
| plain | `just pdf-plain` | `dist/collatz-vermutung-plain.pdf` |
|
||||
| nur assemblieren | `just assemble` | `build/book.md` |
|
||||
|
||||
**Print/KDP (separater Skill):** `pdf-print` / `/pdf-print` → `just pdf-print` → `dist/collatz-vermutung-print.pdf` (6×9 Grayscale).
|
||||
|
||||
## Ablauf
|
||||
|
||||
### 1. Klären und vorbereiten
|
||||
|
||||
- Build-Art mit User abstimmen, falls unklar (default: full).
|
||||
- Optional: `just clean` für sauberen Neu-Build.
|
||||
|
||||
### 2. Bauen
|
||||
|
||||
```bash
|
||||
just pdf
|
||||
# oder: just pdf-draft | just pdf-plain
|
||||
```
|
||||
|
||||
**Typische Fehler:**
|
||||
|
||||
| Fehler | Ursache | nächster Schritt |
|
||||
|--------|---------|------------------|
|
||||
| `pandoc` / `lualatex` missing | Tool fehlt im PATH | Installation / Host-TeX |
|
||||
| LaTeX-Error | Template, Zeichen, Paket | Log in `dist/` / Terminal lesen |
|
||||
| Pandoc-Error | Markdown-Syntax | zuletzt geänderte `0x-*.md` |
|
||||
| Assembler-Error | Kapitel fehlt / Reihenfolge | `scripts/assemble_book.py` (dynamischer `NN-*.md`-Glob) |
|
||||
|
||||
→ Verifikation: Ziel-PDF existiert und ist > 0 Bytes.
|
||||
|
||||
### 3. QA (nach full / wenn verlangt)
|
||||
|
||||
```bash
|
||||
just qa
|
||||
```
|
||||
|
||||
Prüft u. a. Existenz, Seitenzahl (Info, kein Soft-Limit), Keywords (Collatz, Vermutung, Zyklus, Stoppzeit, 3n+1), Fonts.
|
||||
|
||||
→ Warnungen dokumentieren; echte Fehler beheben oder als blockierend melden.
|
||||
|
||||
### 4. Ergebnis melden
|
||||
|
||||
```text
|
||||
## Build-Ergebnis
|
||||
**Datei:** dist/…
|
||||
**QA:** bestanden / Warnungen / Fehler
|
||||
**Notizen:** …
|
||||
```
|
||||
|
||||
## Aufräumen
|
||||
|
||||
```bash
|
||||
just clean
|
||||
```
|
||||
|
||||
Nur wenn gewünscht — löscht generierte Build-/PDF-Artefakte.
|
||||
@@ -0,0 +1,160 @@
|
||||
# Bau-Pipeline — Die Collatz-Vermutung
|
||||
|
||||
Build-Regeln für die PDF-Pipeline dieses Buchs.
|
||||
|
||||
---
|
||||
|
||||
## Kommandos
|
||||
|
||||
| Kommando | Wirkung | Wann |
|
||||
|----------|---------|------|
|
||||
| `just assemble` | Root-`NN-*.md` (ohne `00`) → `build/book.md` | Debug Assembler / Callouts |
|
||||
| `just pdf` | assemble + pandoc/lualatex → `dist/collatz-vermutung.pdf` | eBook A4 Farbe (wenn Build verlangt) |
|
||||
| `just pdf-draft` | Draft-PDF mit Wasserzeichen | Review-Runden |
|
||||
| `just pdf-plain` | ohne gestyltes Template | schneller Layout-Vergleich |
|
||||
| `just pdf-print` | assemble + Grayscale-Assets + KDP 6×9 → `dist/…-print.pdf` | Paperback-Interior |
|
||||
| `just print-assets` | nur `scripts/prepare_print_assets.py` | Debug Bild-Prep |
|
||||
| `just qa` | `scripts/check_pdf.py` (eBook) | nach `just pdf` |
|
||||
| `just qa-print` | `scripts/check_pdf.py --mode print` | nach `just pdf-print` |
|
||||
| `just all` | pdf + qa | Release-nahe Prüfung eBook |
|
||||
| `just all-print` | pdf-print + qa-print | Release-nahe Prüfung Print |
|
||||
| `just clean` | `build/` + dist-PDF-Artefakte | sauberer Neu-Build |
|
||||
|
||||
PDF nur bauen, wenn der Task es verlangt. eBook und Print sind **parallele** Outputs.
|
||||
|
||||
## Pipeline
|
||||
|
||||
```text
|
||||
01-….md … NN-….md (Root-Kapitel, dynamisch via NN-*.md-Glob; 00-inhaltsverzeichnis bleibt draußen)
|
||||
│
|
||||
▼ scripts/assemble_book.py
|
||||
build/book.md (Kern-/Achtung-Callouts → guidekern / guideachtung)
|
||||
│
|
||||
▼ pandoc --pdf-engine=lualatex
|
||||
--template=pdf/templates/guide.tex
|
||||
-H pdf/styles/guide-colors.tex
|
||||
--metadata-file=pdf/metadata.yaml
|
||||
--lua-filter=pdf/filters/tables.lua
|
||||
--resource-path=.:assets:…
|
||||
│
|
||||
▼
|
||||
dist/collatz-vermutung.pdf
|
||||
│
|
||||
▼ scripts/check_pdf.py
|
||||
QA: Existenz, Seitenzahl (Info), Keywords, Fonts
|
||||
```
|
||||
|
||||
### Print / KDP (Paperback Interior)
|
||||
|
||||
```text
|
||||
build/book.md (gleicher Assembler)
|
||||
│
|
||||
▼ scripts/prepare_print_assets.py
|
||||
build/print-assets/ (Grayscale-JPGs, 300-DPI-Metadata; MD-Pfad-Spiegel)
|
||||
│
|
||||
▼ pandoc --pdf-engine=lualatex
|
||||
--template=pdf/templates/guide.tex (print-interior: true)
|
||||
-H pdf/print/print-colors.tex
|
||||
--metadata-file=pdf/print/metadata.yaml
|
||||
--lua-filter=pdf/filters/tables.lua (-V printmode=true)
|
||||
--syntax-highlighting=monochrome (Code ohne RGB)
|
||||
resource-path: build/print-assets:… zuerst
|
||||
│
|
||||
▼
|
||||
dist/collatz-vermutung-print.pdf
|
||||
│
|
||||
▼ scripts/check_pdf.py --mode print
|
||||
QA: 6×9, Fonts, Seiten, Keywords, Gray-Stage, pdfimages gray
|
||||
```
|
||||
|
||||
| Print-Datei | Rolle |
|
||||
|-------------|--------|
|
||||
| `pdf/print/metadata.yaml` | 6×9 geometry, twoside, 10 pt, linestretch 1,22 |
|
||||
| `pdf/print/print-colors.tex` | Grayscale-Palette (gleiche Farbnamen) |
|
||||
| `pdf/print/print-preamble.tex` | Sans-Body, Kopf/Fuß außen, Callouts B/W, Cover-Titelseite |
|
||||
| `scripts/prepare_print_assets.py` | RGB → Grayscale + Kontrast |
|
||||
|
||||
**KDP-Spec (Interior):** Trim 6×9 in · White Paper · kein Bleed · inner **0,65"** · outer **0,60"** · top **0,70"** · bottom **1,00"** · headsep **0,12"** · footskip **0,30"** (Footer-Ink ≈ **0,65″**, Header-Ink ≈ **0,45″**) · Titelseite Cover-Safe-Frame **0,30"** · Figuren Gin **0,87** (1280 px ≈ 300 DPI) · openany · Body **10 pt** (TeX Gyre Heros Scale=1.0) · linestretch **1,22** · Box/Code 9 pt · Schriften embedded. Optional: `just pdf-print-optimize` (Ghostscript Gray/prepress).
|
||||
**Cover-PDF** (Bleed/Spine) ist **nicht** Teil dieser Pipeline. Interior-Titelseite nutzt `assets/cover/cover-front-print.jpg` (Fallback: `cover-front.jpg`). Hinweise: `pdf/print/QA-NOTES.md`.
|
||||
|
||||
**Nicht im PDF:** `00-inhaltsverzeichnis.md`, `README.md`, `HANDOFF-collatz.md`, `kladde.md`, `docs/**`.
|
||||
**Leser-Vorlagen:** dieses Projekt hat keine `templates/`/`checklists/`-Ebene — das Inhaltsverzeichnis definiert verbindliche Abschluss-Labels pro Kapitel.
|
||||
|
||||
### PDF-Inhaltsverzeichnis (kuratiert)
|
||||
|
||||
- `toc-depth: 1` in `pdf/metadata.yaml` (Kapitel + `##`; **keine** `###`).
|
||||
- Zielumfang: **ca. 2–3 Seiten** (nicht die volle Outline).
|
||||
- Im IV: Kapitel + **inhaltstragende** `##` (Lernachse: These, Mechanik, Kernpraxis).
|
||||
- **Nicht** im IV (`{.unnumbered .unlisted}` an der `##`-Zeile): Key Takeaways / Praktische nächste Schritte (bereits), reine Checklisten, Matrizen-only, Mapping-Anhänge, „Häufige Einwände“, Katalog-Unterkapitel ohne eigene These, dünne Satellite-Abschnitte, Anhang-Unterpunkte A.x/B.x (nur Anhang-Titel).
|
||||
- **Pandoc 3.x/LaTeX:** `.unlisted` allein genügt nicht — immer mit `.unnumbered` kombinieren.
|
||||
- PDF-Bookmarks (`bookmarksdepth=2` in `guide-preamble.tex`) dürfen tiefer/ voller sein als das gedruckte IV.
|
||||
|
||||
## Callout-Transform (Assembler)
|
||||
|
||||
`scripts/assemble_book.py` mappt:
|
||||
|
||||
- Blockquotes mit Label **Kern** / **Kern in einem Satz** → `guidekern`
|
||||
- Blockquotes mit Label **Achtung** → `guideachtung`
|
||||
- Blockquotes mit Label **These N** / **These** → `guidekern` (Kompatibilität; für dieses Buch normalerweise „Kern“)
|
||||
- Blöcke **Jetzt selbst machen** → `guideuebung` (falls später genutzt)
|
||||
|
||||
Mehrere Labels in *einem* fortlaufenden Blockquote werden in **eigene Boxen** gesplittet — sonst erscheint nur das erste Label. Im Manuskript trotzdem lieber mit Leerzeile trennen (Lesbarkeit).
|
||||
|
||||
Diese Marker im Manuskript nicht „verschönern“ oder in andere Markdown-Konstrukte umbauen.
|
||||
|
||||
## Wichtige Build-Dateien
|
||||
|
||||
| Pfad | Rolle | Bearbeiten? |
|
||||
|------|-------|-------------|
|
||||
| `NN-*.md` (Root, ohne `00`) | Quellkapitel | ✅ ja |
|
||||
| `scripts/assemble_book.py` | Concat + Callouts | ⚠️ nur mit Auftrag |
|
||||
| `scripts/check_pdf.py` | QA eBook + Print (`--mode`) | ⚠️ nur mit Auftrag |
|
||||
| `scripts/prepare_print_assets.py` | Grayscale-Assets für Print | ⚠️ nur mit Auftrag |
|
||||
| `pdf/templates/*`, `pdf/filters/*`, `pdf/styles/*` | Layout eBook | ⚠️ nur mit Auftrag |
|
||||
| `pdf/print/*` | Layout KDP Interior | ⚠️ nur mit Auftrag |
|
||||
| `pdf/metadata.yaml` | Metadaten eBook | ✅ bei Meta-Tasks |
|
||||
| `pdf/print/metadata.yaml` | Metadaten Print | ✅ bei Print-Meta-Tasks |
|
||||
| `pdf/front/impressum.tex` | Impressum | ✅ bei Meta-Tasks |
|
||||
| `pdf/back/ueber-den-autor.tex` | Über den Autor (Backmatter) | ✅ bei Meta-Tasks |
|
||||
| `assets/**` | Cover/Bilder (optional) | ✅ bei Illustrations-Tasks |
|
||||
| `build/`, `dist/*` | generiert | ❌ neu bauen, nicht handpatchen |
|
||||
|
||||
## QA (`just qa` / `just qa-print`)
|
||||
|
||||
**eBook (`just qa`):**
|
||||
|
||||
- PDF existiert und ist nicht leer
|
||||
- Seitenzahl: nur Info (kein Soft-Limit)
|
||||
- Keywords u. a.: Collatz, Vermutung, Zyklus, Stoppzeit, 3n+1
|
||||
- Font-Embedding, falls `pdffonts` verfügbar
|
||||
|
||||
**Print (`just qa-print`):**
|
||||
|
||||
- wie eBook, plus **Page size ≈ 6×9 in** (432×648 pt)
|
||||
- Soft-Seitenzahl: ca. 120–320
|
||||
- Gray-Stage + `pdfimages` DeviceGray
|
||||
- Ausgabe manueller Prüfpunkte (Diagramme, Tabellen, DPI)
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
| Symptom | Prüfen |
|
||||
|---------|--------|
|
||||
| `pandoc: command not found` | PATH / Installation |
|
||||
| `lualatex: command not found` | TeX Live auf dem Host |
|
||||
| Assembler-Fehler | Kapiteldateien vorhanden und nach `NN-*.md` benannt? (dynamischer Glob) |
|
||||
| fehlende Bilder im PDF | Pfade unter `assets/`, `resource-path` im justfile |
|
||||
| Print-Bilder farbig | Stage muss MD-Pfade spiegeln (`build/print-assets/assets/…`); resource-path `build/print-assets` zuerst; QA: `pdfimages -list` → color=gray |
|
||||
| Print-Code farbig | `--syntax-highlighting=monochrome` in `just pdf-print` (eBook-Default bleibt farbig) |
|
||||
| Print nicht 6×9 | `pdf/print/metadata.yaml` geometry; Template `print-interior` |
|
||||
| Callout fehlt im PDF | Label-Schreibweise (`**Kern:**` / `**Achtung:**`) im Markdown |
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
`pandoc`, `just`, TeX Live (LuaLaTeX, KOMA-Script `scrbook`), Python 3 + **Pillow**.
|
||||
|
||||
| Build | Fonts (Host / TeX Live) |
|
||||
|-------|-------------------------|
|
||||
| eBook | IBM Plex Serif / Sans / Mono (+ DejaVu-Fallback; `guide-preamble.tex`) |
|
||||
| Print | TeX Gyre Heros + DejaVu Sans Mono (siehe `print-preamble.tex`) |
|
||||
|
||||
**Outfit (Branch `outfit`):** eBook `DIV=11`, **linestretch 1.15**, IBM Plex Serif/Sans/Mono, aggressives microtype (protrusion/expansion), luftigere Kapitel. Callouts mit Teal/Coral-Semantik (`guide-colors.tex`: These=Teal, Achtung=Coral `#E07A5F`, Takeaways=Slate, Next=Grün-Teal; Do/Avoid-Header). Key-Takeaways/Nächste-Schritte via `pdf/filters/takeaways.lua`, Tabellen via `tables.lua` + `colortbl`. Print: Box/Header-Parität (Grayscale-Tokens), KDP-Ränder und Heros-Fonts unverändert.
|
||||
@@ -0,0 +1,133 @@
|
||||
---
|
||||
name: pdf-print
|
||||
description: >
|
||||
Baut die druckfertige KDP-Paperback-Interior-PDF (6×9 in, Grayscale) für
|
||||
„Die Collatz-Vermutung“ und führt Print-QA aus.
|
||||
Nutzen bei: „Print-PDF“, „KDP Interior“, „Paperback bauen“, „6x9“,
|
||||
„pdf-print“, /pdf-print.
|
||||
when-to-use: >
|
||||
User will Print/KDP-Interior (6×9 Grayscale) bauen oder Print-QA. Nicht für eBook (pdf-bauen).
|
||||
Nur bei explizitem Auftrag ausführen.
|
||||
argument-hint: "[full|qa|assets]"
|
||||
---
|
||||
|
||||
# PDF-Print-Skill — KDP Interior (6×9 Grayscale)
|
||||
|
||||
Parallele Pipeline zur eBook-PDF. eBook bleibt `just pdf` / Skill `pdf-bauen`.
|
||||
|
||||
Details (nur bei Build-Task laden): `.commandcode/skills/pdf-bauen/references/pipeline.md` → Abschnitt „Print / KDP“.
|
||||
|
||||
## Prinzipien
|
||||
|
||||
1. Denken vor dem Schreiben — Fehler analysieren, bevor blind neu gebaut wird.
|
||||
2. Einfachheit — nur die Build-Art, die nötig ist.
|
||||
3. Chirurgisch — während des Bauens keine Manuskript-Edits „nebenbei“.
|
||||
4. Zielgetrieben — fertig erst, wenn Print-PDF und Print-QA stehen.
|
||||
|
||||
## Spec (KDP Interior)
|
||||
|
||||
| Parameter | Wert |
|
||||
|-----------|------|
|
||||
| Trim | 6 × 9 in |
|
||||
| Farbe | Grayscale (White Paper); Code: `--syntax-highlighting=monochrome` |
|
||||
| Bleed | nein |
|
||||
| Ränder | inner **0,65"** · outer **0,60"** · top **0,70"** · bottom **1,00"** (Footer-Ink ≈ 0,65″) · headsep **0,12"** (Header-Ink ≈ 0,45″) · footskip **0,30"** |
|
||||
| Typo | Body **10 pt** (Scale=1.0) · Leading ~14,6 pt · Box/Code **9 pt** |
|
||||
| Titelseite | Cover im **0,30"**-Safe-Frame (KDP-Außen ≥ 0,25") |
|
||||
| Figuren | Gin `0,87\linewidth` → 1280 px ≈ 300 DPI |
|
||||
| Output | `dist/collatz-vermutung-print.pdf` |
|
||||
| PDF | 1.4–1.7, Schriften embedded; optional GS Gray (`just pdf-print-optimize`) |
|
||||
|
||||
## Build-Arten
|
||||
|
||||
| Art | Kommando | Output |
|
||||
|-----|----------|--------|
|
||||
| full (default) | `just pdf-print` | assemble + grayscale assets + Print-PDF |
|
||||
| nur Assets | `just print-assets` | `build/print-assets/` |
|
||||
| GS-Optimize | `just pdf-print-optimize` | Gray/prepress-Nachlauf auf Print-PDF |
|
||||
| nur QA | `just qa-print` | Checks auf existierendes Print-PDF |
|
||||
| full + QA | `just all-print` | pdf-print + qa-print |
|
||||
|
||||
**eBook (unabhängig):** `just pdf` → `dist/collatz-vermutung.pdf`
|
||||
|
||||
## Ablauf
|
||||
|
||||
### 1. Klären und vorbereiten
|
||||
|
||||
- Default: full Print-Build + QA.
|
||||
- Optional: `just clean` nur wenn sauberer Neu-Build gewünscht (löscht auch eBook-PDF in `dist/`).
|
||||
|
||||
### 2. Bauen
|
||||
|
||||
```bash
|
||||
just pdf-print
|
||||
```
|
||||
|
||||
Pipeline intern:
|
||||
|
||||
1. `scripts/assemble_book.py` → `build/book.md`
|
||||
2. `scripts/prepare_print_assets.py` → Grayscale-JPGs unter `build/print-assets/assets/…` (MD-Pfad-Spiegel, damit resource-path die Gray-Version vor RGB findet)
|
||||
3. pandoc + LuaLaTeX mit `pdf/print/*` (6×9, twoside, hidelinks, monochrome Syntax)
|
||||
|
||||
**Typische Fehler:**
|
||||
|
||||
| Fehler | Ursache | nächster Schritt |
|
||||
|--------|---------|------------------|
|
||||
| `pandoc` / `lualatex` missing | Tool fehlt im PATH | Installation / Host-TeX |
|
||||
| Font not found (TeX Gyre Heros) | TeX Live unvollständig | `texlive-fonts-recommended` / TeX Gyre |
|
||||
| LaTeX-Error | print-preamble, geometry | Log in Terminal lesen |
|
||||
| PIL/Pillow missing | Asset-Prep | `pip install pillow` |
|
||||
| Overfull hbox | schmale Tabellen/Code | `tables.lua` / Code umbrechen |
|
||||
|
||||
→ Verifikation: `dist/collatz-vermutung-print.pdf` existiert und > 0 Bytes.
|
||||
|
||||
### 3. QA
|
||||
|
||||
```bash
|
||||
just qa-print
|
||||
```
|
||||
|
||||
Prüft u. a.: Existenz, Seitenzahl (Soft 120–320), Font-Embedding, Keywords, **Page size ≈ 6×9 in**, Gray-Stage, eingebettete Bilder grayscale.
|
||||
|
||||
### 4. Ergebnis melden
|
||||
|
||||
```text
|
||||
## Build-Ergebnis (Print / KDP)
|
||||
**Datei:** dist/collatz-vermutung-print.pdf
|
||||
**Format:** 6×9 in · Grayscale · twoside
|
||||
**Seiten:** …
|
||||
**QA:** bestanden / Warnungen / Fehler
|
||||
**eBook unverändert:** dist/collatz-vermutung.pdf (falls nicht mit-clean)
|
||||
|
||||
### Änderungs-Checkliste (Pipeline)
|
||||
- [ ] Trim 6×9, Ränder inner 0,65", outer 0,60", top 0,70", bottom 1,00" (Footer-Ink ≈ 0,65"); headsep 0,12" / footskip 0,30"
|
||||
- [ ] Titelseite Cover-Safe-Frame ≥ 0,30"
|
||||
- [ ] Grayscale-Palette + grayscale Assets + monochrome Code-Highlight
|
||||
- [ ] Figuren Gin 0,87 → ~300 DPI bei 1280 px
|
||||
- [ ] Sans-Body TeX Gyre Heros **10 pt Scale=1.0**, Mono/Box/Code ~9 pt
|
||||
- [ ] Seitenzahlen außen; Kolumnentitel dezent
|
||||
- [ ] Schriften embedded; kein Media-Box-Overflow (Impressum)
|
||||
- [ ] Keine unnötigen Kapitel-Leerseiten (openany)
|
||||
|
||||
### Manuelle Nacharbeit (bei Bedarf)
|
||||
- Farbgetriebene Diagramme einzeln prüfen (Farbe war Information?)
|
||||
- Cover: natives ≥1800×2700 (cover-front-print.jpg)
|
||||
- Sehr breite Tabellen im schmalen Satzspiegel
|
||||
- Optional: just pdf-print-optimize vor KDP-Upload
|
||||
```
|
||||
|
||||
## Aufräumen
|
||||
|
||||
```bash
|
||||
just clean
|
||||
```
|
||||
|
||||
Löscht `build/` (inkl. print-assets) und `dist/*.pdf`.
|
||||
|
||||
## Abgrenzung
|
||||
|
||||
| Skill / Command | Rolle |
|
||||
|-----------------|--------|
|
||||
| `pdf-bauen` / `/pdf` | A4 eBook (Farbe) |
|
||||
| **`pdf-print` / `/pdf-print`** | KDP Interior 6×9 B/W |
|
||||
| KDP-**Cover** | separat (Bleed + Spine) — nicht dieser Skill |
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
name: total-check
|
||||
description: >
|
||||
Nutze bei buchweiter Vollprüfung aller Aspekte mit Sub-Agenten:
|
||||
„total-check", „/total-check", „Vollprüfung", „prüfe das gesamte Buch",
|
||||
„alle sinnvollen Prüfungen", „Prüfprotokoll".
|
||||
Nicht für Einzelkapitel-Lektorat, einzelne Abbildungen oder PDF-Build.
|
||||
when-to-use: >
|
||||
User will eine buchweite Vollprüfung oder ein Prüfprotokoll. Nicht für ein einzelnes
|
||||
Kapitel (lektorat/kapitel-review), nicht für eine Figur, nicht für PDF-Build.
|
||||
---
|
||||
|
||||
# Total-Check — Vollprüfung
|
||||
|
||||
Buchweite Prüfung aller sinnvollen Spuren mit Sub-Agenten; Ergebnis ist ein Prüfprotokoll.
|
||||
|
||||
Struktur portiert aus dem Schwesterprojekt *Coding Agents in der Praxis*, angepasst an *Die Collatz-Vermutung*. Der Roster wird beim Lauf aus dem Inventar berechnet (Kapitelzahl, Figurenzahl) — die Wellen-Logik bleibt.
|
||||
|
||||
**Modus:** Report only. Keine Manuskript-, Asset- oder Pipeline-Edits. Kein Rebuild. Kein Commit. Handoff nur wenn der User es verlangt.
|
||||
|
||||
**Parent arbeitet nicht selbst als Prüfer.** Inventar + Synthese ja; Kapitel-, Bild- und QA-Urteile kommen von Sub-Agenten.
|
||||
|
||||
Prompts: `references/agent-prompts.md`. Dateigerüst: `references/protokoll.md`.
|
||||
|
||||
## Nicht tun
|
||||
|
||||
| Ausrede | Regel |
|
||||
|---------|--------|
|
||||
| „Ich lese die Kapitel selbst, das ist genauer.“ | Nein. Roster spawnen. |
|
||||
| „Gegenleser reichen.“ | Nein. Pro Kapitel Gegenlese **und** Lektorat **und** Fakten-Check. |
|
||||
| „Bilder mache ich stichprobenartig.“ | Nein. Eine Agentin pro Figur (sobald Figuren existieren). |
|
||||
| „Welle 2 spare ich, die Funde sind klar.“ | Neue P1 ohne Skeptiker gelten nicht als bestätigt. |
|
||||
| Bild-FAIL = Text-P0 | Bild-QA bleibt Bild-QA. |
|
||||
| Bekannte Handoff-Schnitte als „neu“ | Als *bekannt* listen, Grep ob noch im Text. |
|
||||
|
||||
## Wellen
|
||||
|
||||
```
|
||||
Welle 0 Inventar (Parent)
|
||||
→ Welle 1: Roster aus Inventar (parallel, nicht zusammenlegen)
|
||||
→ Welle 2: bis 9 Skeptiker auf neue P1
|
||||
→ Synthese → reviews/vollpruefung-YYYY-MM-DD.md
|
||||
```
|
||||
|
||||
### Welle 0 — Parent
|
||||
|
||||
Read-only plus QA-Kommandos. Kein `just pdf` / `just pdf-print`.
|
||||
|
||||
1. HEAD, Branch, dirty tree (`git status -sb`, `git log -1`).
|
||||
2. Manuskript-Inventar: Root-`NN-*.md` vs. `00-inhaltsverzeichnis.md` (Kapitelzahl, verbindliche Labels).
|
||||
3. Forschungsbasis: `docs/` vollständig (10 Dateien), unverändert gegen letzten Commit?
|
||||
4. Abbildungs-Inventar (falls `assets/illustrations/` existiert): JPGs vs. Katalog.
|
||||
5. Offene Handoff-Punkte per Grep: noch im Text oder gesetzt?
|
||||
6. Letztes `reviews/vollpruefung-*.md` nur als Prior-Kontext, **Urteile nicht kopieren**.
|
||||
7. Artefakt-mtime (falls `dist/*.pdf` existiert) vs. letzter Manuskript-Stand → STALE markieren.
|
||||
|
||||
### Welle 1 — Roster (aus Inventar)
|
||||
|
||||
Sofort alle starten (`background: true`). Host-Limit → restliche nachziehen, nicht mergen.
|
||||
|
||||
Typ: `explore` (read-only), außer QA (`general`).
|
||||
|
||||
| Rolle | N | Auftrag |
|
||||
|-------|---|---------|
|
||||
| Gegenleser | je Kapitel | Skill `kapitel-review` |
|
||||
| Lektor | je Kapitel | Skill `lektorat`. **Keine Edits.** |
|
||||
| Fakten | je Kapitel | Claims vs. `docs/` (Forschungsbasis); Faktenschutz |
|
||||
| Lesepass | 4 | je 1: Wiederholungen, Brücken, Terminologie, Ton/Faktenschutz |
|
||||
| Quellen | 1 | `docs/08-references.md` Live-Check der im Manuskript zitierten Keys/URLs |
|
||||
| Formalia | 1 | Impressum/Meta/Cover (sobald vorhanden) |
|
||||
| Navigation | 1 | `00`-Titel = Datei-H1; README-Lesepfade; Cross-Refs |
|
||||
| QA | 2 | `just qa` · `just qa-print` (falls Dist existiert). Kein Rebuild. |
|
||||
| Abbildungen | je Figur | Checkliste `abbildung/references/qa-checklist.md` |
|
||||
| Harness | 1 | `AGENTS.md`/Skills/Commands vs. Dateien; Assembler vs. `NN-*.md` |
|
||||
|
||||
Jeder Prompt aus `references/agent-prompts.md`.
|
||||
|
||||
### Welle 2 — Skeptiker
|
||||
|
||||
Aus Welle 1 die **neuen** P1 (nicht Handoff-Altbestand). Ziel: 9. Weniger Kandidaten → einer pro Fund. Mehr → die 9 mit höchstem Schaden (Mehrspur oder Widerspruch zu Faktenschutz/Schreibkonventionen).
|
||||
|
||||
Typ: `explore`, read-only. Ausgabe nur `real=true` oder `real=false` plus Begründung. Keine neuen Baustellen erfinden.
|
||||
|
||||
Nur `real=true` darf im Protokoll unter „Neue P1 — bestätigt“ stehen.
|
||||
|
||||
## Synthese
|
||||
|
||||
Datei: `reviews/vollpruefung-YYYY-MM-DD.md` nach `references/protokoll.md`.
|
||||
|
||||
Im Chat nur Executive Summary + Pfad. Rohberichte bleiben in der Session.
|
||||
|
||||
P0 = textlich falsch, irreführend **oder Faktenschutz-Bruch**. Bild-FAIL und STALE-Artefakte sind keine Text-P0.
|
||||
|
||||
Nächste Schnitte nur als Empfehlung, nicht umsetzen.
|
||||
|
||||
## Wann nicht
|
||||
|
||||
- Ein Kapitel / ein Bild / Humanizer → die Einzel-Skills (`/lektorat`, `/gegenlese`, `/humanizer`, `/abbildung`).
|
||||
- Umsetzen von Funden → nach Freigabe `/lektorat` oder expliziter Edit-Auftrag.
|
||||
- PDF bauen → `/pdf`.
|
||||
@@ -0,0 +1,146 @@
|
||||
# Total-Check — Agent-Prompts
|
||||
|
||||
Parent kopiert den passenden Block und ersetzt die Klammern. Jeder Prompt endet mit dem Ausgabe-Vertrag. Keine Datei schreiben, keine Edits.
|
||||
|
||||
Gemeinsamer Kopf (allen voranstellen):
|
||||
|
||||
```
|
||||
Projekt: /Volumes/SSD2TB/work/collatz
|
||||
Buch: „Die Collatz-Vermutung“ (Sachbuch für Laien). Ton: verlässlicher Erklärer — präzise, geduldig, ehrlich, ohne Hype und ohne Sensationsgier.
|
||||
Modus: READ-ONLY. Keine Datei anlegen, ändern, löschen. Kein Commit, kein Rebuild.
|
||||
Faktenschutz: Die Vermutung ist unbewiesen (Stand 2026). Verifikationsgrenze 2^71 (Barina), Tao „fast alle“ (log-Dichte, 2022), Zyklen-Grenzen m ≤ 91 (Hercher 2023), Undecidability nur für Generalisierungen (Conway 1972; Kurtz–Simon 2007) — nur in der docs/-Formulierung.
|
||||
Faktenkanon: docs/ (englische Forschungsbasis, 10 Dateien); URLs nur in docs/08-references.md.
|
||||
P0 = falsch/irreführend/Faktenschutz-Bruch. P1 = ungenau/inkonsistent. P2 = Stil/optional.
|
||||
Zeilennummern aus der Datei, nicht schätzen.
|
||||
Vorheriges Protokoll reviews/vollpruefung-*.md nicht als Wahrheit übernehmen.
|
||||
```
|
||||
|
||||
## Gegenleser (je Kapitel)
|
||||
|
||||
`subagent_type: explore` · Datei eine aus den Root-`NN-*.md`.
|
||||
|
||||
```
|
||||
Lade .commandcode/skills/kapitel-review/SKILL.md.
|
||||
Prüfe [DATEI] vollständig (4 Dimensionen). Nachbarn nur bei Bruch/Echo.
|
||||
Ausgabe: Gesamteindruck; P0/P1/P2 mit Zeile + Vorschlag; Verhältnis zum Gesamtbuch.
|
||||
```
|
||||
|
||||
## Lektor (je Kapitel)
|
||||
|
||||
`subagent_type: explore`
|
||||
|
||||
```
|
||||
Lade .commandcode/skills/lektorat/SKILL.md. Checkpoints 1–7 auf [DATEI].
|
||||
Forschungsbasis nur lesen (docs/0*.md). KEINE Edits, auch nicht bei P0.
|
||||
Ausgabe: Lektorats-Report mit Statistik.
|
||||
```
|
||||
|
||||
## Fakten (je Kapitel)
|
||||
|
||||
`subagent_type: explore`
|
||||
|
||||
```
|
||||
Claims in [DATEI] gegen docs/ (Forschungsbasis; Themenschlüssel: docs/kb/00-projekt/forschungsbasis.md).
|
||||
Jede mathematische Behauptung: Formulierung identisch mit docs/? Autor+Jahr-Zitat im Text?
|
||||
Keine erfundenen Zahlen, Namen, Zitate. Verifikation ≠ Beweis. Heuristik ≠ Beweis.
|
||||
„Ungelöst bleibt ungelöst“ — kippt der Text irgendwo in Scheinlösung?
|
||||
Ausgabe: geprüfte Claims grob; P0/P1/P2 mit Passage, Problem, Vorschlag, Quelle (docs-Datei).
|
||||
```
|
||||
|
||||
## Lesepass (4)
|
||||
|
||||
`subagent_type: explore`
|
||||
|
||||
| Agent | Fokus |
|
||||
|-------|-------|
|
||||
| lesepass-wiederholungen | Vermutung/Drift/Zyklen — echte Doppel-Erklärungen ohne Mehrwert |
|
||||
| lesepass-bruecken | Nähte zwischen den Kapiteln laut 00-inhaltsverzeichnis.md |
|
||||
| lesepass-terminologie | Stoppzeit ≠ Gesamtstoppzeit; Shortcut-Map; log-Dichte; Verifikationsgrenze |
|
||||
| lesepass-ton | Hype, Sensationsgier, Genie-Kitsch, Scheinlösungen; „ungelöst bleibt ungelöst“ |
|
||||
|
||||
```
|
||||
Nur Spur: [FOKUS]. Scope: alle NN-*.md.
|
||||
Terminologie-Kanon: .commandcode/rules/schreibkonventionen.md § Terminologie.
|
||||
Ausgabe: P0/P1/P2 dieser Spur, Datei + Zeile, Vorschlag (streichen/verweisen/einmal ausführlich).
|
||||
```
|
||||
|
||||
## Quellen (1)
|
||||
|
||||
```
|
||||
docs/08-references.md — die im Manuskript zitierten Autor+Jahr-Keys.
|
||||
Live-Check soweit möglich (DOI/URL). Pro Eintrag: OK / OK* / FAIL.
|
||||
OK* = erreichbar, aber Auflage/URL/Typ unscharf. FAIL nur bei totem oder falschem Key.
|
||||
Eigene URLs (Projekt, Begleitmaterial) extra prüfen.
|
||||
```
|
||||
|
||||
## Formalia (1)
|
||||
|
||||
```
|
||||
pdf/front/impressum.tex, pdf/back/ueber-den-autor.tex (falls vorhanden),
|
||||
pdf/metadata.yaml, pdf/print/metadata.yaml, Cover-Text (falls vorhanden).
|
||||
Titel identisch (Arbeitstitel-Wandel: Meta konsistent?); Stand-Angaben gleich.
|
||||
P2 reicht für Typografie.
|
||||
```
|
||||
|
||||
## Navigation (1)
|
||||
|
||||
```
|
||||
00-inhaltsverzeichnis.md Titel = jeweilige Datei-H1; verbindliche Abschluss-Labels konsistent?
|
||||
README-Lesepfade zeigen auf existierende Kapitel.
|
||||
Cross-Refs (Kap. n, docs/0x) stichprobenartig auf reale Abschnitte.
|
||||
```
|
||||
|
||||
## QA (2)
|
||||
|
||||
`subagent_type: general` · **kein Rebuild**. Nur falls `dist/*.pdf` existiert.
|
||||
|
||||
```
|
||||
Nur prüfen, nicht bauen.
|
||||
[ebook] just qa + pdfinfo dist/collatz-vermutung.pdf (Seiten, mtime, Fonts).
|
||||
[print] just qa-print + MediaBox 432×648, gray vs RGB, mtime vs eBook.
|
||||
STALE = älter als letzter Manuskript-Stand.
|
||||
Ausgabe: Tabelle Check/Ist/Status (PASS|WARN|FAIL|STALE).
|
||||
```
|
||||
|
||||
## Abbildung (je Figur, falls vorhanden)
|
||||
|
||||
Eine Figur pro Agent. `read_file` auf dem JPG.
|
||||
|
||||
```
|
||||
ID [ID]. Pfad und Caption aus dem Katalog.
|
||||
Lies das JPG multimodal. Caption im Kapitel (eine Primärstelle).
|
||||
Checkliste: .commandcode/skills/abbildung/references/qa-checklist.md (soweit Spec).
|
||||
Urteil: PASS | PASS* | P2 | FAIL.
|
||||
PASS* = Pflicht gehalten, Restfehler (Extra-Titel, kleine Typos).
|
||||
FAIL = Pflichtbruch (Garbled, falsche Reihenfolge/Zahlen, verbotene Motive).
|
||||
Bild-FAIL ist kein Text-P0. Labels EN, Caption DE.
|
||||
Ausgabe: eine Zeile ID | Urteil | Caption ja/nein | Pflicht/Rest | eine Begründung.
|
||||
```
|
||||
|
||||
## Harness (1)
|
||||
|
||||
```
|
||||
AGENTS.md Skill-/Command-Liste vs. .commandcode/skills/ und .commandcode/commands/.
|
||||
Schreibkonventionen-Import (@-Referenz) auflösbar?
|
||||
scripts/assemble_book.py Kapitel-Glob = NN-*.md, ohne 00 / HANDOFF / reviews / docs / kladde.
|
||||
kladde.md nicht in der Pipeline.
|
||||
```
|
||||
|
||||
## Welle 2 — Skeptiker (≤9)
|
||||
|
||||
```
|
||||
Du bist unabhängiger Skeptiker. Auftrag: ist dieser Fund real?
|
||||
|
||||
Claim: [ZITAT]
|
||||
Datei: [DATEI] Zeile [N]
|
||||
Behauptung der Welle 1: [PROBLEM]
|
||||
Vorschlag der Welle 1: [VORSCHLAG]
|
||||
Lies die Stelle + nötige Karten unter docs/kb/. Suche die entlastende Lesart zuerst.
|
||||
|
||||
Antwort exakt:
|
||||
real: true|false
|
||||
grund: [3–8 Sätze]
|
||||
falls true, schärferer Vorschlag: […]
|
||||
|
||||
Keine neuen Funde. Kein Edit.
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
# Protokoll-Gerüst
|
||||
|
||||
Schreiben nach `reviews/vollpruefung-YYYY-MM-DD.md` (Kalenderdatum des Laufs). Vorlage nicht als alten Befund kopieren. Roster-Zahlen aus dem Welle-0-Inventar einsetzen.
|
||||
|
||||
```markdown
|
||||
# Vollprüfung — Die Collatz-Vermutung (Sachbuch)
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| **Datum** | YYYY-MM-DD |
|
||||
| **Branch / HEAD** | `branch` @ `sha` |
|
||||
| **Dirty** | Dateien oder „sauber“ |
|
||||
| **Methode** | Welle 0 Inventar · Welle 1 = N Agenten (Roster aus Inventar) · Welle 2 = N Skeptiker · Synthese |
|
||||
| **Modus** | Report only. Keine Manuskript-, Asset- oder Pipeline-Edits. Kein Rebuild. |
|
||||
| **Agenten** | N (Kapitelspuren, Lesepass, Quellen, Formalia, Navigation, QA, Abbildungen, Harness, N Verifikatoren) |
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
Trägt das Buch? Text-P0 ja/nein (inkl. Faktenschutz-Brüche). Was Welle 2 bestätigt / verworfen hat (Stichworte).
|
||||
Produktion: eBook / Print (falls vorhanden: Seiten, QA, STALE).
|
||||
Abbildungen: N geprüft, FAIL nur IDs.
|
||||
Nächster Schnitt nur als Empfehlung.
|
||||
|
||||
## 2. Statistik
|
||||
|
||||
| Spur | Ergebnis |
|
||||
|------|----------|
|
||||
| Text-P0 | N |
|
||||
| Faktenschutz-Brüche | N |
|
||||
| Neue P1, Welle 2 bestätigt | N |
|
||||
| Neue P1-Kandidaten, nicht verifiziert | N |
|
||||
| Handoff-P1 noch im Text | … |
|
||||
| Quellen | a/b OK |
|
||||
| eBook / Print QA | … |
|
||||
| Abbildungen | N · FAIL-IDs |
|
||||
|
||||
## 3. Coverage-Matrix
|
||||
|
||||
Status nur: PASS / WARN / FAIL / STALE / N/A / OFFEN.
|
||||
|
||||
### Integrität
|
||||
Manuskript vs. 00-inhaltsverzeichnis · `docs/` unverändert · Dirty dokumentiert.
|
||||
|
||||
### Kapitel
|
||||
Tabelle Einheit | Gegenlese | Lektorat | Fakten.
|
||||
|
||||
### Querschnitt
|
||||
Ton/Positionierung · Terminologie · Fakten/Faktenschutz · Didaktik (Laien-Tauglichkeit) · Hygiene · eBook · Print · Navigation · Legal.
|
||||
|
||||
## 4. P0
|
||||
|
||||
Keine erfinden. Bild-FAIL hier nicht listen.
|
||||
|
||||
## 5. Neue P1 — Welle 2 bestätigt
|
||||
|
||||
Nur `real=true`. Tabelle ID | Stelle | Problem | Vorschlag | Verifikator.
|
||||
Danach: Welle 2 verworfen (`real=false`) mit Grund.
|
||||
|
||||
## 6. Weitere neue P1 (nicht Welle-2-verifiziert)
|
||||
|
||||
Keine stillen Edits daraus ableiten.
|
||||
|
||||
## 7. P1 bekannt
|
||||
|
||||
HANDOFF-collatz.md: gesetzt oder noch im Text (Grep-Beleg).
|
||||
|
||||
## 8. P2 (Auswahl)
|
||||
|
||||
Kein Blocker. Caption-Nits, Formalia, Rhythmus.
|
||||
|
||||
## 9. Produktion (falls Dist existiert)
|
||||
|
||||
Untertabellen eBook / Print: mtime, Seiten/Größe, QA-Kommando, STALE-Grund.
|
||||
Kein EPUB in dieser Pipeline.
|
||||
|
||||
## 10. Abbildungen (falls vorhanden)
|
||||
|
||||
Eine Zeile pro ID: Urteil | Caption | Pflicht/Rest.
|
||||
FAIL-Liste separat. Cover eigene Zeile.
|
||||
|
||||
## 11. Fakten / Stand
|
||||
|
||||
Wo Manuskript-Text und `docs/` zusammen- oder auseinanderlaufen; Stand-Angaben mit Datum/Quelle geprüft?
|
||||
|
||||
## 12. Empfohlene nächste Schnitte
|
||||
|
||||
Nur mit Auftrag. Keine Umsetzung in diesem Lauf.
|
||||
|
||||
## 13. Anhang
|
||||
|
||||
Welle-0-Rohzeilen. Agenten ohne Ergebnis. Satz: kein Lektorat-Umsetzen, kein Regen, kein Commit.
|
||||
```
|
||||
Whitespace-only changes.
+37
@@ -0,0 +1,37 @@
|
||||
.DS_Store
|
||||
*.log
|
||||
|
||||
# Secrets
|
||||
.env
|
||||
.env.*
|
||||
secrets/
|
||||
|
||||
# Python (falls später Scripts/Build)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
.venv/
|
||||
*.egg-info/
|
||||
.pytest_cache/
|
||||
.ruff_cache/
|
||||
|
||||
# Build / Export (PDF-Pipeline)
|
||||
build/
|
||||
dist/*.aux
|
||||
dist/*.log
|
||||
dist/*.out
|
||||
dist/*.toc
|
||||
# dist/*.pdf bewusst nicht ignoriert (lokaler/optionaler Artefakt-Stand ok)
|
||||
|
||||
# Roh-Drops für Abbildungen (Kanon: assets/illustrations/ bzw. assets/cover/)
|
||||
pics/
|
||||
|
||||
# Agent-Lärm / lokale Backups (Kanon bleibt assets/illustrations/*.jpg;
|
||||
# Figuren-Rollback ist assets/illustrations/_backup-svg/ — getrackt, nicht ignorieren)
|
||||
assets/cover/_backup/
|
||||
**/.DS_Store
|
||||
|
||||
# Editor / local agent state (optional)
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
kladde.md
|
||||
@@ -0,0 +1,56 @@
|
||||
// Tight-Loop Markdown — Manuskript + Leser-Templates + Root-AGENTS.md
|
||||
// Pandoc-Buchstil: viele Regeln aus, die Prosa/Attribute/Takeaways zerlegen.
|
||||
// An bleibt, was Agent-Edits typisch kaputtmachen (leere Links, Tabs, trailing space).
|
||||
{
|
||||
"globs": [
|
||||
"AGENTS.md",
|
||||
"0*.md",
|
||||
"1*.md",
|
||||
"2*.md",
|
||||
"templates/**/*.md",
|
||||
"checklists/**/*.md"
|
||||
],
|
||||
"ignores": [
|
||||
"docs/**",
|
||||
"reviews/**",
|
||||
"knowledge/**",
|
||||
"build/**",
|
||||
"dist/**",
|
||||
"kladde.md",
|
||||
"HANDOFF*.md"
|
||||
],
|
||||
"config": {
|
||||
"default": true,
|
||||
"MD013": false,
|
||||
"MD024": false,
|
||||
"MD025": false,
|
||||
"MD026": false,
|
||||
"MD027": false,
|
||||
"MD028": false,
|
||||
"MD033": false,
|
||||
"MD034": false,
|
||||
"MD036": false,
|
||||
"MD040": false,
|
||||
"MD041": false,
|
||||
"MD046": false,
|
||||
"MD048": false,
|
||||
"MD049": false,
|
||||
"MD050": false,
|
||||
"MD051": false,
|
||||
"MD055": false,
|
||||
"MD056": false,
|
||||
"MD058": false,
|
||||
"MD001": false,
|
||||
"MD003": false,
|
||||
"MD004": false,
|
||||
"MD007": false,
|
||||
"MD012": false,
|
||||
"MD022": false,
|
||||
"MD029": false,
|
||||
"MD030": false,
|
||||
"MD031": false,
|
||||
"MD032": false,
|
||||
"MD035": false,
|
||||
"MD047": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
# Inhaltsverzeichnis
|
||||
|
||||
> Kapitelbogen des Sachbuchs „Die Collatz-Vermutung" · Stand: 2026-08-29 · Faktengrundlage: `docs/` (Faktenkanon) · **Flag** = Recherche-Bedarf: Fakten wandern erst bei Kapitelarbeit in `docs/` (mit Quelle), dann ins Manuskript.
|
||||
>
|
||||
> Status der Vermutung: **unbewiesen** (Stand 2026). Verifikationsgrenze `2^71` ist Beobachtung, kein Beweis. Kein Kapitel suggeriert „gelöst".
|
||||
|
||||
## Leitidee
|
||||
|
||||
**Ein Satz, den jedes Kind versteht — und den die Mathematik seit fast 90 Jahren nicht entscheidet.** Das Buch erzählt nicht „die Formel", sondern eine Kulturgeschichte des Staunens: Warum ist so etwas Einfaches so hartnäckig, welche Werkzeuge fehlen (und wurden bei anderen Problemen erfunden), und warum gehört ehrliches Scheitern hier zur Wissenschaft. Ton: verlässlicher Erklärer — präzise, geduldig, ehrlich, ohne Hype und ohne Mystifikation. Der Leser kann jede Aussage an einer kleinen Zahl prüfen; jede große Behauptung ist etikettiert (Theorem, Heuristik, Computerfakt oder offene Frage).
|
||||
|
||||
---
|
||||
|
||||
## Teil I — Einladen und spielen
|
||||
|
||||
*Die Lust entsteht zuerst. Noch keine Forschungslage.*
|
||||
|
||||
### 0 · Vorspiel: Nimm eine Zahl
|
||||
|
||||
- **These/Frage:** Wie sieht die Regel beim Spielen aus? Mit 7, 13 und vor allem 27 mitrechnen — Auf und Ab, Gipfel 9232, Landung im Kreis 1 → 4 → 2 → 1. Pointe: „Das ist die ganze Vermutung — der Rest des Buchs erklärt, warum niemand weiß, ob sie wahr ist."
|
||||
- **Bild:** Hagelkorn (steigt in der Wolke, fällt zu Boden — *hailstone numbers*).
|
||||
- **Label:** Einladung
|
||||
- **Kanon:** `docs/01` §1.1–1.2, `docs/04` §4.4
|
||||
- **Würze:** xkcd 710 („…eventually your friends will stop calling…" — wörtlich, Quelle in `docs/08`); Abbildungs-Kandidat: Bahn von 27 (Auf und Ab, Absturz ins 4-2-1-Tal).
|
||||
- **Flag:** —
|
||||
|
||||
### 1 · Ein Problem, viele Namen
|
||||
|
||||
- **These/Frage:** Wer „erfand" es? Collatz: Notizbuch 1932 mit früheren Iterationsproblemen und graphischer Sicht; das 3n+1 selbst Hamburg 1937, nach eigener späterer Erinnerung damals unveröffentlicht (Vortragsreisen inkl. ICM 1950); Weitergabe über Hasse („Syracuse" — Name geprägt bei Hasse-Besuch der Syracuse University), Ulam (Los Alamos), Kakutani (Yale/Chicago), Thwaites (1952; £1000, als anekdotisch etikettiert). Pointe: Das Problem ist so natürlich, dass es mehrfach „erfunden" wurde.
|
||||
- **Bild:** Wanderlegende.
|
||||
- **Label:** Erzählung
|
||||
- **Würze:** Kakutani-Anekdote wörtlich („For about a month everybody at Yale worked on it…" + Chicago + Verschwörungs-Witz, Lagarias 1985); Coxeters $50 (1970, „mathematical gossip") und Erdős' $500 als Gesprächseinschätzung; Collatz-Prioritätsbrief (Abbildung via Mays/CECM).
|
||||
- **Kanon:** `docs/01` §1.3–1.5, `docs/08` (Preise, Kultur-Quellen)
|
||||
- **Flag:** Gardner 1972 (Scientific American) · Jahreszahl des Collatz-Prioritätsbriefs
|
||||
|
||||
### 2 · Die Regel ohne Formelpanzer
|
||||
|
||||
- **These/Frage:** Was heißt „immer bei 1 landen" genau? Gerade: halbieren; ungerade: 3n+1; Shortcut `T(n) = (3n+1)/2` einmal benennen. 27 als große Reise; Delay- und Path-Records als Landschaft (frühe Rekordhalter: 871: τ=178, 6171: τ=261, 77031: τ=350, 837799: τ=524; aktuelle via Roosendaal); negative Zahlen mit drei bekannten Kreisen — „immer 1" ist keine Selbstverständlichkeit. Rechenstand sachlich: geprüft bis `2^71`, beeindruckend und kein Beweis.
|
||||
- **Bild:** Rückwärts gewachsener Baum (Koralle): Die Vermutung sagt, er enthält alle positiven ganzen Zahlen.
|
||||
- **Label:** Blick zurück
|
||||
- **Kanon:** `docs/01` §1.2, `docs/02` (Shortcut, inverser Baum), `docs/04` §4.2/§4.4, `docs/06` §6.1, `docs/08` (OEIS)
|
||||
- **Flag:** —
|
||||
|
||||
## Teil II — Warum das so schwer ist
|
||||
|
||||
*Intuition vor „aktuellem Stand".*
|
||||
|
||||
### 3 · Was man zu sehen glaubt
|
||||
|
||||
- **These/Frage:** Warum *sollte* fast alles schrumpfen? Auf eine ungerade Zahl folgt **immer** eine gerade; je Schritt ist man zur Hälfte bei ×1/2, zur Hälfte bei ×3/2 — im Mittel schrumpft die Zahl (typischer Faktor ≈ 0,866, Stoppzeit grob 6,95·ln n). Und trotzdem: Einzelbahnen schießen weit nach oben. „Im Schnitt" heißt nichts „für jede einzelne Zahl" — der rote Faden bis Tao.
|
||||
- **Bild:** Würfel-Walk mit Gefälle.
|
||||
- **Label:** Erkenntnis
|
||||
- **Kanon:** `docs/05` §5.1
|
||||
- **Flag:** —
|
||||
|
||||
### 4 · Drei Arten, falsch zu sein
|
||||
|
||||
- **These/Frage:** (1) ein anderer endlicher Kreis, (2) eine Bahn, die für immer wächst, (3) etwas Pathologisches dazwischen. Was man weiß: keine kleinen nichttrivialen Kreise — Kreislängen müssten absurd lang sein (keine m-Zyklen für m ≤ 91; Kombination mit `2^71`), Divergenz ist das hartnäckigere Gespenst. 5n+1 als Labor: beide Versagensmodi real.
|
||||
- **Bild:** Gespenster-Triptychon.
|
||||
- **Label:** Erkenntnis
|
||||
- **Kanon:** `docs/03` §3.3, `docs/06` §6.1–6.2
|
||||
- **Flag:** —
|
||||
|
||||
### 5 · Erste ernsthafte Sätze
|
||||
|
||||
- **These/Frage:** Was ließ sich beweisen: Terras 1976 (unabhängig Everett 1977) — fast alle Zahlen fallen irgendwann unter ihren Startwert; Dichte-Ergebnisse; Conway 1972 — verallgemeinerte Regeln können Rechner simulieren. Erdős: „Die Mathematik ist dafür noch nicht reif." Lagarias als Chronist des Feldes.
|
||||
- **Bild:** Kartierungsbeginn.
|
||||
- **Label:** Erkenntnis
|
||||
- **Würze:** Warn-Kultur mit Beleg: Guy 1983 (Kolumnen-Titel „Don't try to solve these problems!", vier 3x+1-artige Probleme, keins gelöst); Lagarias „really dangerous problem" (Quanta 2019); Kontorovich „Fall nicht in diese Falle" — ignoriert (Harper's 2025); Erdős' $500 als Gesprächseinschätzung.
|
||||
- **Kanon:** `docs/03` §3.1, `docs/06` §6.3, `docs/01` §1.3/§1.5, `docs/08`
|
||||
- **Flag:** —
|
||||
|
||||
## Teil III — Die Jagd
|
||||
|
||||
*Forschung, Ideen, Schiffbrüche — wertschätzend, sachlich.*
|
||||
|
||||
### 6 · Rechenstand und Rekorde
|
||||
|
||||
- **These/Frage:** Was bedeutet „geprüft bis 2^71"? Barina-Projekt (2^68 → 2^71, 2025), Roosendaal-Datenbank, Rekord-Landschaft — und die Grenze: Verifikation ist Beobachtung, kein Beweis. Ehrlich bleiben: systematisch geprüft ist der Bereich bis `2^71`; darüber hinaus nur Einzelfälle, keine systematische Prüfung.
|
||||
- **Bild:** Fernglas.
|
||||
- **Label:** Blick zurück
|
||||
- **Kanon:** `docs/04`
|
||||
- **Flag:** —
|
||||
|
||||
### 7 · Fast alle — der Tao-Satz
|
||||
|
||||
- **These/Frage:** Wie nah kann Statistik ran? Tao 2022 (Preprint 2019): fast alle Bahnen erreichen **fast beschränkte** Werte (*almost bounded*, logarithmische Dichte — kanonische Formulierung `docs/03` §3.2) — so nah am Ziel, wie Statistik reichen kann; und trotzdem kann eine einzige widerspenstige Zahl genügen. Kein Vollbeweis.
|
||||
- **Bild:** Flutmarke.
|
||||
- **Label:** Erkenntnis
|
||||
- **Kanon:** `docs/03` §3.2, `docs/08`
|
||||
- **Flag:** —
|
||||
|
||||
### 8 · Beweisideen und Analogien
|
||||
|
||||
- **These/Frage:** Welche Werkzeuge probiert man? Rückwärtsbaum und Überdeckung; 2-adische Brille (Shortcut-Map als Shift-Map); Paritätsfolgen als Zufall; Transferoperatoren; Dynamik-Bilder. Jede Idee: Was sie erklärt, wo sie hängen bleibt. Warum Addition und Multiplikation hier ineinander verkeilt sind — markiert als Bild.
|
||||
- **Bild:** Werkzeugkasten.
|
||||
- **Label:** Werkstatt
|
||||
- **Kanon:** `docs/02`
|
||||
- **Flag:** Automaten/Umschreibsysteme als Beweisidee (nicht kanonisch)
|
||||
|
||||
### 9 · Die Kartierung der Fehlversuche
|
||||
|
||||
- **These/Frage:** Wo scheitert es typisch? Versteckte Lücke bei „fast allen", Heuristik=Beweis-Verwechslung, Induktionsanfang, Computerargument ohne Restklassenkontrolle. Fallstudie Opfer 2011; Preprint-Flut; KI- und Lean-„Beweise" inkl. Lean-Kernel-Vorfall 2026 — als Warnung, nicht als Skandal. Ein ehrlicher Fehlversuch ist Teil der Mathematik; ein undurchsichtiger „Beweis" ist es nicht.
|
||||
- **Bild:** Bergführer-Protokoll (Friedhofs-Metapher möglich, aber als markiertes Bild).
|
||||
- **Label:** Blick zurück
|
||||
- **Würze:** soziale Seite — Nerd Sniping (xkcd 356: „a certain type of brain that's easily disabled"); heutige Memekultur („Lösungen" per Mail an Professoren, ChatGPT-Anekdoten, Antiklimax-Witz) — als Volkskultur erzählen, ohne Einzelbehauptungen.
|
||||
- **Kanon:** `docs/09`, `docs/07` §7.3
|
||||
- **Flag:** —
|
||||
|
||||
## Teil IV — Collatz im Konzert der großen Probleme
|
||||
|
||||
*Vergleiche als Ausblick — Kapitel nur schreiben, nachdem die Fakten in `docs/` recherchiert sind (mit Quelle).*
|
||||
|
||||
### 10 · Gelöste Riesen, fehlende Werkzeuge
|
||||
|
||||
- **These/Frage:** Was lehren Fermat (~350 Jahre), Poincaré (~100 Jahre), Vier-Farben/Kepler über Collatz? Moral: Nicht der Wille fehlt — oft fehlt das Feld; manche Sätze warten, bis die Brücke zu einem ganz anderen Ufer gebaut ist.
|
||||
- **Bild:** Brückenbau.
|
||||
- **Label:** Ausblick
|
||||
- **Kanon:** (außerhalb Kanons)
|
||||
- **Flag:** komplette Vergleichstafel (Wiles/elliptische Kurven/Modularität, Perelman/Ricci-Fluss, Computer als Beweismittel, Klassifikation endlicher Gruppen)
|
||||
|
||||
### 11 · Offene Nachbarn
|
||||
|
||||
- **These/Frage:** Goldbach, Primzahlzwillinge, Riemann, ungerade vollkommene Zahlen, Busy Beaver — wo steht Collatz im Feld? Manche sind „fast sicher und großflächig geprüft", manche haben eine Theorie drumherum; Collatz sitzt dazwischen: kinderleicht zu sagen, strukturell widerspenstig, statistisch „fast wahr".
|
||||
- **Bild:** Nachbargärten.
|
||||
- **Label:** Ausblick
|
||||
- **Kanon:** (außerhalb Kanons)
|
||||
- **Flag:** komplette Vergleichsmaterie inkl. Prüfgrenzen
|
||||
|
||||
## Teil V — Was bleibt
|
||||
|
||||
### 12 · Der Horizont: Unentscheidbarkeit
|
||||
|
||||
- **These/Frage:** Könnte Collatz ein Gödel-Tor sein? Redlich bleiben: Conway 1972 und Kurtz–Simon 2007 treffen **verwandte** Familien, nicht die klassische 3n+1-Regel; ein Beweis der Unabhängigkeit existiert nicht. Wäre die klassische Vermutung unentscheidbar, wäre das selbst eine Sensation — andeuten, nicht spekulieren. Nicht jedes verschlossene Tor ist ein Gödel-Tor; manche sind nur noch nicht geschmiedet.
|
||||
- **Bild:** verschlossene Tore.
|
||||
- **Label:** Ausblick
|
||||
- **Kanon:** `docs/06` §6.3
|
||||
- **Flag:** Gödel-Formulierung/CH-Detail (vorsichtig, Laien-gerecht recherchieren)
|
||||
|
||||
### 13 · Was ein Beweis wert wäre — Nachwort
|
||||
|
||||
- **These/Frage:** Warum lohnt die Jagd — und warum auch ohne Schatz? Ein Beweis würde vermutlich neue Werkzeuge pflügen (so wie Fermat und Poincaré ihre Felder); ohne Beweis hat Collatz Visualisierung, Informatik, Zufallsmodelle und die Demut der Disziplin geprägt. Schlussbild: der Korallenbaum, der weiterwächst, solange niemand eine Zahl findet, die sich weigert, nach Hause zu kommen.
|
||||
- **Bild:** Korallenbaum.
|
||||
- **Label:** Nachwort
|
||||
- **Würze:** Growneys Gedicht „A Mathematician's Nightmare" (Allgemeinladen, Spiegel für 27 Dollar, 59 Tage warten — nutzt die Shortcut-Formel (3n+1)/2, daher 70 Schritte/Peak 4616 in ihrer Zählung: Fußnoten-Chance); Antiklimax-Witz („im Alltag ändert sich nichts") als Kontrastfolie zum Wert-ohne-Beweis-Argument.
|
||||
- **Kanon:** `docs/07` §7.1
|
||||
- **Flag:** —
|
||||
|
||||
---
|
||||
|
||||
## Verbindliche Abschluss-Labels
|
||||
|
||||
Die Labels sind mit Freigabe dieses ToC **unveränderbar** (AGENTS.md: Kapitel-Abschlüsse werden im Inhaltsverzeichnis festgelegt).
|
||||
|
||||
| Label | Bedeutung | Kapitel |
|
||||
|---|---|---|
|
||||
| Einladung | Kapitel endet mit offener Neugier, ohne Ergebniszwang | 0 |
|
||||
| Erzählung | Kapitel endet mit gedeuteter Geschichte (kein Moral-Kitsch) | 1 |
|
||||
| Blick zurück | Kapitel endet mit „Was feststeht" — kurze, etikettierte Bilanz | 2, 6, 9 |
|
||||
| Erkenntnis | Kapitel endet mit einem Satz, der bleibt (etikettiert: Theorem/Heuristik/Beobachtung) | 3, 4, 5, 7 |
|
||||
| Werkstatt | Kapitel endet mit offenem Werkzeugzustand: was trägt, was nicht | 8 |
|
||||
| Ausblick | Kapitel endet mit Blick über das Feld, klar als Ausblick markiert | 10, 11, 12 |
|
||||
| Nachwort | Schlusswort, kein Cliffhanger | 13 |
|
||||
|
||||
**Gilt für alle Kapitel:** kein Quiz, keine Übungsaufgaben, kein „Merke-Kasten"-Zwang (Laien-Sachbuch ≠ Do-it-Buch). Fachbegriffe beim Erstauftreten erklären; Analogien sind markierte Vergleichshilfen („Bild, kein Beweis").
|
||||
|
||||
## Lesepfade
|
||||
|
||||
- **Schnellkurs:** 0 → 3 → 4 → 7 → 12 (das Wesen in fünf Kapiteln)
|
||||
- **Volltour:** 0–13
|
||||
- **Rechenpfad:** 0 → 2 → 3 → 6 (anschaulich bis Verifikation)
|
||||
- **Geschichtspfad:** 1 → 5 → 9 → 13 (Menschen, Sätze, Schiffbrüche)
|
||||
|
||||
## Anhänge (geplant)
|
||||
|
||||
- **A · Glossar:** Bahn, Gesamtstoppzeit vs. Stoppzeit (kanonische Terminologie!), m-Zyklus, logarithmische Dichte, 2-adische Zahlen — je ein Satz.
|
||||
- **B · Kommentierte Literatur:** Grundlage `docs/08` (URLs ausschließlich dort). Populäre Einstiege (Veritasium, Numberphile, Gardner-Recherche) mit Hinweis auf Popularisierung; vgl. `docs/kb/02-recherche/video-inhaltskarte.md`.
|
||||
- **C · Berühmte Startwerte:** Tabelle mit 27 (τ=111, M=9232) und frühen Rekordhaltern 871 (τ=178), 6171 (τ=261), 77031 (τ=350), 837799 (τ=524); aktuelle Rekorde via Roosendaal (`docs/04` §4.4, Quelle `docs/08`).
|
||||
|
||||
## Regeln für die Arbeit mit diesem ToC
|
||||
|
||||
- **Flag = Recherche-Bedarf:** Nicht-kanonische Bausteine (oben) sind keine Fakten. Erst `docs/` ergänzen (mit Quelle + Datum), dann Kapitel schreiben.
|
||||
- **Faktenschutz:** Grenzen/Rekorde/„fast alle" nur in den kanonischen Formulierungen (`AGENTS.md` § Faktenschutz).
|
||||
- **Ton:** verlässlicher Erklärer; keine Mystifikation, keine „gelöst!"-Framings; Heuristik heißt Heuristik; gescheiterte Versuche sachlich.
|
||||
- **Würze:** Auflockerung (Anekdote, Zitat, Comic, Gedicht) nur an den mit „Würze" gekennzeichneten Stellen; jedes Element mit Quelle in `docs/08` oder klar als Folklore etikettiert; keine ungefragten Exkurse.
|
||||
- **Kapiteldateien:** `NN-*.md` im Root (Kapitel 0 = `00-vorspiel.md`); `00-inhaltsverzeichnis.md` selbst ist vom PDF-Assembler ausgeschlossen und Kapitelplan, kein Buchtext.
|
||||
- Metaphern-Haushalt: ein Leitbild pro Kapitel (Hagelkorn, Koralle, Gefälle, Gespenster, Fernglas, Flutmarke, Werkzeugkasten, Brückenbau, Nachbargärten, Tore).
|
||||
@@ -0,0 +1,72 @@
|
||||
# AGENTS.md — Collatz-Sachbuch
|
||||
|
||||
Projekt-Regeln für Coding-Agents am Sachbuch. Karpathy-Prinzipien, adaptiert.
|
||||
Qualität vor Tempo. Bei trivialen Edits nach eigenem Ermessen.
|
||||
|
||||
**Titel:** *Die Collatz-Vermutung* (Arbeitstitel)
|
||||
**Publikum:** Laien ohne mathematische Vorbildung — neugierige Erwachsene.
|
||||
**Ton:** verlässlicher Erklärer — präzise, geduldig, ehrlich, ohne Hype und ohne Sensationsgier.
|
||||
|
||||
## 1. Denken vor dem Schreiben
|
||||
|
||||
- Annahmen explizit. Bei Unsicherheit: **nachfragen**.
|
||||
- Mathematische Fakten: nicht raten und nicht aus dem Gedächtnis ergänzen. **Faktenkanon: `docs/`** (englische Recherche-Doku, 10 Dateien; URLs zentral nur in `docs/08-references.md`). Primärquellen schlagen Blogposts.
|
||||
- Stand-Angaben (Rekorde, Publikationen, Verifikationsgrenzen): nur mit Datum und Quelle.
|
||||
|
||||
## 2. Einfachheit zuerst
|
||||
|
||||
- Nüchtern, klar, zugänglich; keine ungefragten Exkurse, Kapitelumstellungen oder „interessanten Fakten“.
|
||||
- Deutsch durchgängig; Personennamen und Fachbegriffe original (Collatz, Erdős, Lagarias; *stopping time*, *logarithmic density* bei Erstnennung mit Übersetzung).
|
||||
- **Laien-tauglich:** Jeder Fachbegriff beim ersten Auftreten im Kapitel erklärt. Formeln sparsam und immer umgangssprachlich aufgelöst. Analogien ausdrücklich als Vergleichshilfe markieren („Bild, kein Beweis“).
|
||||
- **Keine Mathematik-Mystifikation:** „ungelöst bleibt ungelöst“. Keine „gelöst!“-Framings, keine dramatisierenden Übertreibungen, keine erfundenen Namen, Zitate oder Zahlen.
|
||||
|
||||
## 3. Chirurgische Änderungen
|
||||
|
||||
- Nur anfassen, was der Task verlangt.
|
||||
- **`docs/` (Forschungsbasis) nicht ohne Auftrag ändern** — sie ist der Faktenkanon; das Manuskript leitet sich daraus ab.
|
||||
- **`kladde.md` nicht ohne Auftrag** ändern oder löschen.
|
||||
|
||||
## 4. Zielgetrieben
|
||||
|
||||
- Erfolgskriterien prüfbar. Nach dem Schreiben Ziel und DoD kurz wiederholen (Teach-back).
|
||||
- Kapitel-Abschlüsse: im Inhaltsverzeichnis pro Kapitel festgelegt (Laien-Sachbuch ≠ Do-it-Buch); verbindliche Labels gelten dann unveränderbar.
|
||||
- Workflow: Explore → Plan → Execute → Verify → Commit (Commit nur wenn erlaubt).
|
||||
|
||||
## Faktenschutz
|
||||
|
||||
Die in `docs/` verbürgten Fakten nicht still abschwächen, dramatisieren oder ausdehnen:
|
||||
|
||||
- Die Vermutung ist **unbewiesen** (Stand 2026). Kein Satz darf das Gegenteil nahelegen.
|
||||
- Barina-Verifikationsgrenze `2^71`, Taos „fast alle“-Satz, Zyklen-Grenzen `m ≤ 91`, Undecidability der Generalisierung: nur in den in `docs/` dokumentierten Formulierungen.
|
||||
- Gescheiterte Beweisversuche (`docs/09-failed-attempts.md`) sachlich erzählen — nicht als Skandal-Stories oder Heldengeschichten.
|
||||
- Neu recherchierte Fakten landen **erst** in `docs/` (mit Quelle), dann im Manuskript.
|
||||
|
||||
## Compact / Handoff
|
||||
|
||||
- Session-Context schlank und signalstark halten.
|
||||
- Bei Rauschen oder Fokusverlust: Compact vorschlagen, fertigen Hint anbieten (Ziel, DoD, eine Invariante, nächste Schritte).
|
||||
- Nach Compact: Ziel, DoD und eine harte Invariante kurz wiederholen; bei Fail Hint nachlegen oder Handoff.
|
||||
- Bei Themenwechsel, Phasengrenze oder Pollution: `HANDOFF-collatz.md` aktualisieren und neue Session empfehlen.
|
||||
- Compact ≠ Handoff ≠ Hand-back. Datei = Handoff.
|
||||
|
||||
## Verify
|
||||
|
||||
Tight-Loop (nach Manuskript-Patches): `just markdownlint` · `just link-check`.
|
||||
Slice-DoD: dieselbe Kette + `git diff --name-only` gegen den Auftrag.
|
||||
Heavy: `just qa` / `just qa-print` nur mit explizitem PDF-Auftrag.
|
||||
|
||||
## Session-Start
|
||||
|
||||
1. Diese Datei — Command Code lädt sie automatisch.
|
||||
2. `docs/kb/INDEX.md` — erste Informationsquelle (nicht den KB-Tree oder die Kapitel dumpen).
|
||||
3. `HANDOFF-collatz.md` — nur bei Fortsetzung / unfertigem Slice.
|
||||
|
||||
Schreibregeln: `@.commandcode/rules/schreibkonventionen.md` — Kapitel-Jobs: Skills `lektorat` / `kapitel-review` / `humanizer`.
|
||||
|
||||
## Nicht ohne Auftrag
|
||||
|
||||
`kladde.md` · `docs/` (Forschungsbasis) · Gesamtrewrite · PDF bauen · `pdf/` / Assembler / QA-Scripts · EPUB · Faktenschutz-Wortlaut · destruktive Git-Ops · Secrets committen.
|
||||
|
||||
## Placement
|
||||
|
||||
Richtlinie hier. Fakten-Map `docs/kb/`. Session `HANDOFF-collatz.md`. Pfad-Rollen `docs/kb/00-projekt/repo-karte.md`. Prozedur Skills / `just`.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Handoff: Sachbuch „Die Collatz-Vermutung“
|
||||
|
||||
> Meta-Arbeitsdokument (nicht Teil der Buchkapitel-Navigation).
|
||||
> **Schreibfläche:** SHA / Dist / Dirty nur in Meta. Freeze nur in § Slice. Offen nur in der Tabelle.
|
||||
|
||||
## Meta
|
||||
|
||||
| Feld | Wert |
|
||||
|------|------|
|
||||
| Datum | 2026-08-29 |
|
||||
| Projektpfad | `/Volumes/SSD2TB/work/collatz` |
|
||||
| Branch | `main` @ **kein Commit** (Repo frisch initialisiert, alles untracked) |
|
||||
| Status | **Infrastruktur-Aufbau abgeschlossen.** Vorgaben, Skills, Pipeline aus Schwesterprojekt `../books/ki-coding-agents-praxis` übernommen und adaptiert. Tight-Loop grün: `just markdownlint` 0 Fehler, `just link-check` ok. Tools: `just`, `pandoc`, `npx`, `python3` vorhanden (lualatex/TeX unbestätigt). Forschungsbasis `docs/` (10 Dateien, englisch) unverändert. Manuskript noch nicht begonnen. Video-Inhaltskarten-Slice abgeschlossen: KB-Domain `02-recherche/` (Video-Inhaltskarte, geprüft gegen `docs/` + Web), Barina-2020-Bibliografie in `docs/08` korrigiert (Quelle: Springer/Projektseite). Buchstruktur-Slice abgeschlossen: `00-inhaltsverzeichnis.md` entworfen (geprüfte externe Review → Kapitelbogen 0–13 in 5 Teilen, verbindliche Labels, Lesepfade, Recherche-Flags). Folklore-/Auflockerungs-Slice abgeschlossen: Anekdoten-Material geprüft, kanonisiert (`docs/01`, `docs/07`, `docs/08`) und als Würze-Zuweisungen ins ToC eingespielt. Review-Vollabgleich-Slice abgeschlossen: Struktur-Review vollständig gegen das ToC abgeglichen; auflösbare Flags gezogen (Rekordzahlen, „Milliarden-Stellen", Anhang C), 1932-Notizbuch kanonisiert, Tao-Formulierung kanonisch korrigiert. |
|
||||
| Nächste Session | **Neue Session.** Nur mit Auftrag. Queue: 1) Initial-Commit (nur mit Auftrag). 2) Kapitel-Start (`00-vorspiel.md` oder `01-*.md`) — oder `docs/`-Recherche für die ToC-Flags (mit Quelle), je nach Wunsch. |
|
||||
|
||||
## Slice (nicht neu verhandeln)
|
||||
|
||||
Kein offener Slice. Übernahme-Slice geschlossen:
|
||||
|
||||
- `AGENTS.md` + `.commandcode/rules/schreibkonventionen.md` — Faktenschutz statt Thesen-Schutz; Laien-Regeln (Beispiel vor Formel, Analogien markiert, „ungelöst bleibt ungelöst“).
|
||||
- Skills `.commandcode/skills/`: `lektorat`, `kapitel-review`, `humanizer`, `abbildung`, `total-check`, `pdf-bauen`, `pdf-print` (parent-context bewusst nicht übernommen — Grok-spezifisch). Alle Schwester-Bezüge ersetzt; Grep-Abgleich 0 Altbezüge (außer beabsichtigtem Herkunfts-Hinweis im total-check).
|
||||
- Commands `.commandcode/commands/`: `buch-status`, `gegenlese` (umbenannt von `review` — `/review` ist Command-Code-Built-in), `pdf`.
|
||||
- Pipeline: `justfile` (Outputs `collatz-vermutung*.pdf`), `scripts/` (Assembler mit dynamischem `NN-*.md`-Glob statt `CHAPTER_ORDER`-Liste), `pdf/` 1:1, `metadata.yaml` → Arbeitstitel, `check_pdf.py` → Collatz-Keywords.
|
||||
- `docs/kb/` Mini-KB: INDEX (L0, Task-Router), overview, repo-karte, source-of-truth, forschungsbasis, stil-ton, terminologie.
|
||||
- README, `kladde.md` (leer), `reviews/README.md`, `.gitignore`, `.markdownlint-cli2.jsonc` (1:1), `git init -b main`.
|
||||
- Video-Inhaltskarten-Slice geschlossen (2026-08-29): `docs/kb/02-recherche/video-inhaltskarte.md` neu (Ur-Fassung gegen Kanon + Web geprüft: Tao 2022 statt 2019, Pólya-Zahl als Haselgrove-Schranke etikettiert, `2^71` belegt, negative Zyklen konkretisiert, Kurtz–Simon ergänzt, „Neu seit den Videos“-Block, Coding-Abschnitt out-of-scope markiert); `docs/kb/INDEX.md` (Router + Domain 02-recherche); `docs/08-references.md` (Barina 2020: korrekt *J Supercomput* 77 (2021), 2681–2688, zuvor „76 (2020), 9678–9696“ — Quelle Springer-Artikelseite + pcbarina.fit.vut.cz); `HANDOFF-collatz.md` (dieser Eintrag). Keine weiteren `docs/`-Änderungen.
|
||||
- Buchstruktur-Slice geschlossen (2026-08-29): externe Struktur-Review gegen Kanon geprüft und als `00-inhaltsverzeichnis.md` umgesetzt — Kapitelbogen 0–13 in 5 Teilen („spielen“ zuerst), je Kapitel These/Frage, Bild, **verbindliches Abschluss-Label** (Einladung/Erzählung/Blick zurück/Erkenntnis/Werkstatt/Ausblick/Nachwort; kein Quiz/Übungen — Laien-Sachbuch), Kanon-Anker, Recherche-Bedarf-Flag; 4 Lesepfade; Anhänge geplant (Glossar/Literatur/Startwerte). Review-Korrekturen: Tao **2022** (Preprint 2019, nicht 2019), Paritätsaussage deterministisch („nach ungerader Zahl kommt **immer** eine gerade“), Kapitel-9-Titel nüchtern „Die Kartierung der Fehlversuche“ (Friedhofs-Bild nur als markierte Metapher), Kakutani nur Yale. Nicht-kanonische Bausteine (ICM 1950, Gardner 1972, Guy-Zitat, Rekordzahlen 871/6171/837799, „Milliarden-Stellen-Zufallszahlen“, komplette Fermat/Poincaré-Vergleichsmaterie, Gödel/CH-Detail) **nur als Flags** — Fakten wandern bei Kapitelarbeit erst in `docs/`. „Monat bei Yale“ gestrichen (kein Kanon-Beleg, kein Wert). Dateiname exakt `00-inhaltsverzeichnis.md` — wird vom Assembler exkludiert (`scripts/assemble_book.py` Z. 32), landet nicht im PDF. `docs/kb/INDEX.md` Router-Zeile „Kapitelstruktur / Abschluss-Labels“. `HANDOFF-collatz.md` (dieser Eintrag).
|
||||
- Folklore-/Auflockerungs-Slice geschlossen (2026-08-29): eingereichter Anekdoten-Text gegen Primärquellen geprüft; 12 Claims verifiziert und kanonisiert — `docs/01` §1.3 (ICM 1950; Syracuse-Name von Hasse-Besuch geprägt; Kakutani wörtlich „For about a month everybody at Yale worked on it…" + Chicago + Verschwörungs-Witz; Ulam/Los Alamos; Collatz-Prioritätsbrief via Mays/CECM; Erdős-Wortlaut korrigiert: „is not yet ready", Herkunft conversational), §1.5 (Warn-Kultur: Guy 1983, Lagarias „really dangerous problem" via Quanta 2019, Kontorovich „Don't fall into that trap" via Harper's 2025; kultureller Fußabdruck: xkcd 710/356, Growney-Gedicht), `docs/07` (Coxeter $50), `docs/08` (Coxeter 1971, Collatz 1986, neue Sektion „Popular and cultural sources" mit allen URLs). Korrekturen am Fremdtext: Tao **2022** statt 2019; Tao-Zitat gestrichen (unbelegt); Erdős-Gespräch mit **Lagarias** (nicht Graham); Thwaites „My Conjecture" verworfen (nicht belegbar); Collatz-Brief-Jahreszahl „1980" unbelegt → Flag; Zyklus „1 → 4 → 2 → 1" und Verifikation `2^71` kanonisch. `00-inhaltsverzeichnis.md`: Würze-Zuweisungen in Kap. 0/1/5/9/13 (dosierte Auflockerung, Würze-Regel im Regeln-Block); Flags ICM 1950/Thwaites 1952/Ulam-Detail/Guy-Zitat aufgelöst; Kap.-1-Flags jetzt: Gardner 1972, Brief-Jahreszahl. `HANDOFF-collatz.md` (dieser Eintrag). Keine Kapitel-Prosa (Kapitel-Start bleibt eigener Auftrag).
|
||||
- Review-Vollabgleich-Slice geschlossen (2026-08-29): die ursprüngliche Struktur-Review vollständig gegen `00-inhaltsverzeichnis.md` abgeglichen — übrige Lücken geschlossen. `docs/04` §4.4: frühe Delay-Rekordhalter kanonisch (`τ(871)=178`, `τ(6171)=261`, `τ(77031)=350`, `τ(837799)=524`); `docs/08` (Eintrag „OEIS delay records" A006877/A006878, abgeleitet aus Roosendaal); `docs/01` §1.3 (1932-Notizbuch: früheres Permutations-Iterationsproblem, Zyklus mit 8 — **nicht** 3n+1 selbst; graphische Sicht als roter Faden). `00-inhaltsverzeichnis.md`: Kap.-0-Pointe („Das ist die ganze Vermutung…"), Kap.-1-These um Notizbuch 1932, Kap.-2 These/Kanon um Rekordzahlen + Flag aufgelöst, Kap.-6 „Milliarden-Stellen"-Claim verworfen (systematisch nur bis `2^71`, darüber Einzelfälle) + Flag aufgelöst, Kap.-7 Tao kanonisch „fast beschränkte Werte" (*almost bounded*, statt „fast beliebig klein"), Anhang C konkretisiert (Flag aufgelöst). Verbleibende Flags: Gardner 1972, Prioritätsbrief-Jahr, Automaten/Umschreibsysteme, Teil-IV-Vergleichsmaterie (Kap. 10–12). `HANDOFF-collatz.md` (dieser Eintrag).
|
||||
|
||||
## Dirty
|
||||
|
||||
- Alle Dateien untracked — **Initial-Commit nur mit Auftrag** (kein .gitignore-Problem: build/dist/pics/kladde sind abgedeckt).
|
||||
|
||||
## Offen (nur mit Auftrag)
|
||||
|
||||
| Prio | Task | Hinweis |
|
||||
|------|------|---------|
|
||||
| 1 | `00-inhaltsverzeichnis.md` entwerfen | Kapitelstruktur + Labels = danach verbindlich; Laien-Bogen: Vermutung → Beispiele → Werkzeugkasten → was bewiesen ist → Rechnen/Rekorde → Heuristik → gescheiterte Versuche → Generalisierungen → offen |
|
||||
| 2 | Initial-Commit | Repo steht; einmal alle Files committen (mit Auftrag) |
|
||||
| 3 | PDF-Pipeline-Test (`just pdf`) | `pandoc` vorhanden; `lualatex`/TeX-Live erst prüfen; PDF-Bau ohnehin nur mit explizitem Auftrag |
|
||||
|
||||
## Slice-Fallen
|
||||
|
||||
| Risiko | Regel |
|
||||
|--------|--------|
|
||||
| `docs/` anfassen | verboten ohne Auftrag — Faktenkanon; Korrekturen dort nur mit Quelle |
|
||||
| Faktenschutz untergraben | „ungelöst bleibt ungelöst“; Rekorde/Grenzen nur in `docs/`-Formulierung |
|
||||
| `AGENTS.md` aufblasen | schlank halten; Detail in Schreibkonventionen/KB |
|
||||
| Skills des Schwester-Buchs 1:1 behalten | kein Hardcode von „Coding Agents“-Bezügen; bei Funden ersetzen |
|
||||
| PDF bauen ohne Auftrag | `just pdf`/`just qa` nur explizit |
|
||||
| Verbindliche Labels nach IV | Erst nach Abschluss des Inhaltsverzeichnisses gelten Labels als fix — nicht davor verhandeln |
|
||||
@@ -0,0 +1,44 @@
|
||||
# Die Collatz-Vermutung — Sachbuch (Arbeitstitel)
|
||||
|
||||
**Untertitel (Arbeitsfassung):** Die einfachste ungelöste Frage der Mathematik — ein Sachbuch für alle
|
||||
|
||||
Dieses Projekt entwickelt ein **Sachbuch für Laien** zur Collatz-Vermutung: neugierige Erwachsene ohne mathematische Vorbildung. Nüchtern, ehrlich, ohne Hype — und ohne Sensationsgier. Ungelöst bleibt ungelöst.
|
||||
|
||||
## Worum es geht
|
||||
|
||||
Die Vermutung: Man wähle irgendeine positive ganze Zahl. Ist sie gerade, halbiere man sie; ist sie ungerade, verdreifache man sie und addiere 1. Die Vermutung behauptet: egal welche Startzahl — die Folge landet irgendwann bei 1. Kein Beweis ist bekannt (Stand 2026), obwohl die Vorschrift in einen Einzeiler passt.
|
||||
|
||||
## Für wen dieses Buch ist
|
||||
|
||||
- Neugierige Erwachsene ohne mathematische Vorbildung
|
||||
- Leserinnen und Leser, die verstehen wollen, warum ein Einzeiler die Mathematik seit Jahrzehnten beschäftigt
|
||||
- Alle, die wissen wollen, was Mathematik konkret treibt, wenn sie an einem offenen Problem arbeitet
|
||||
|
||||
## Für wen es nicht ist
|
||||
|
||||
- Wer Beweistricksereien oder „endlich gelöst!“-Versprechen sucht
|
||||
- Wer ein Lehrbuch mit Übungsaufgaben will
|
||||
|
||||
## Repo-Struktur
|
||||
|
||||
| Ort | Rolle |
|
||||
|-----|-------|
|
||||
| `docs/` | **Forschungsbasis** (englisch, 10 Dateien) — Faktenkanon; Quellen zentral in `docs/08-references.md` |
|
||||
| `docs/kb/` | Autoren-KB — erste Informationsquelle nach `AGENTS.md` |
|
||||
| `00-*.md`, `NN-*.md` (Root) | Manuskript-Kapitel (noch nicht angelegt) |
|
||||
| `.commandcode/` | Autoren-Harness: Rules, Skills, Commands |
|
||||
| `pdf/`, `scripts/`, `justfile` | PDF-Pipeline (pandoc + lualatex) |
|
||||
| `HANDOFF-collatz.md` | aktueller Slice / Session-Übergabe |
|
||||
| `kladde.md` | privat, nicht ohne Auftrag |
|
||||
|
||||
## Workflow für Coding-Agents
|
||||
|
||||
Regeln: [`AGENTS.md`](AGENTS.md) · Schreibregeln: `.commandcode/rules/schreibkonventionen.md` · KB: `docs/kb/INDEX.md`.
|
||||
|
||||
- Explore → Plan → Execute → Verify → Commit (Commit nur wenn erlaubt)
|
||||
- Tight-Loop nach Patches: `just markdownlint` · `just link-check`
|
||||
- PDF-Bau (`just pdf` / `just qa`) nur mit explizitem Auftrag
|
||||
|
||||
## Quelle der Fakten
|
||||
|
||||
Das Manuskript leitet sich aus der Forschungsbasis ab: [docs/index.md](docs/index.md) → `01`–`09` (u. a. Teilresultate, Heuristiken, gescheiterte Beweisversuche, offene Probleme). Fakten fließen **erst in `docs/`** (mit Quelle), **dann** ins Manuskript — Faktenschutz laut `AGENTS.md`.
|
||||
Vendored
BIN
Binary file not shown.
@@ -0,0 +1,65 @@
|
||||
# 1. Introduction — The Collatz Problem
|
||||
|
||||
## 1.1 The problem
|
||||
|
||||
Define a function on the positive integers:
|
||||
|
||||
```
|
||||
C(n) = n/2 if n is even
|
||||
C(n) = 3n + 1 if n is odd
|
||||
```
|
||||
|
||||
Starting from any `n`, iterate `C` forever, producing a trajectory `n, C(n), C²(n), …`.
|
||||
|
||||
> **The Collatz conjecture.** For *every* positive integer `n`, some iterate equals 1.
|
||||
|
||||
Once the trajectory reaches 1 it is trapped forever in the **trivial cycle**
|
||||
|
||||
```
|
||||
1 → 4 → 2 → 1 → …
|
||||
```
|
||||
|
||||
The conjecture has resisted proof since 1937. It is one of the most famous unsolved problems in mathematics. Its current status, verified bounds, and open questions are tracked in [07-open-problems.md](07-open-problems.md).
|
||||
|
||||
## 1.2 A first example: n = 27
|
||||
|
||||
The trajectory of 27 takes **111 steps** to reach 1 and climbs to a maximum of **9232** — over 342 times its starting value — before collapsing:
|
||||
|
||||
```
|
||||
27 → 82 → 41 → 124 → 62 → 31 → 94 → … → 9232 → 4616 → … → 1
|
||||
```
|
||||
|
||||
Compare with a power of two: `2^k` reaches 1 in exactly `k` steps. Most starting values fall quickly; outliers like 27 show how deceptively irregular the dynamics are. Record-holding trajectories are collected in [04-computational-verification.md](04-computational-verification.md).
|
||||
|
||||
## 1.3 History
|
||||
|
||||
- **1932** — Precursor: in a notebook dated 1 July 1932, Collatz considers a permutation of the natural numbers given by an iteration and poses the problem of determining its cycle structure — in particular whether the cycle containing 8 is finite or infinite (i.e., whether its iterates stay bounded). His graph-theoretic view of number-theoretic functions is the common thread to the later `3n+1` iteration; the 1932 problem is not the `3n+1` problem itself ([Lagarias 1985](08-references.md#lagarias-1985), CECM edition).
|
||||
- **1937** — Lothar Collatz, then in Hamburg, formulates the iteration (per his own later recollections). It is not published at the time — Collatz later wrote: *"Since I could not solve the [3n+1] problem, I did not publish the conjecture"* (quoted in [Opfer 2011](08-references.md#opfer-2011)).
|
||||
- **1950** — Collatz circulates his iteration problems at the International Congress of Mathematicians in Cambridge, Massachusetts ([Lagarias 1985](08-references.md#lagarias-1985)).
|
||||
- **1950s** — The problem spreads through the international community. Helmut Hasse carries it between Hamburg and the USA; the name *Syracuse problem* was proposed by Hasse during a 1950s visit to Syracuse University. Around 1960 Shizuo Kakutani popularizes it: *"For about a month everybody at Yale worked on it, with no result. A similar phenomenon happened when I mentioned it at the University of Chicago. A joke was made that this problem was part of a conspiracy to slow down mathematical research in the U.S."* (Kakutani, quoted in [Lagarias 1985](08-references.md#lagarias-1985)). Stanisław Ulam circulates it at Los Alamos and elsewhere. A two-page letter in which Collatz claims priority as the problem's first student is reproduced at the CECM edition of [Lagarias 1985](08-references.md#cecm-lagarias-1985-site) (courtesy of Mike Mays).
|
||||
- **1970s–1990s** — First rigorous partial results appear: stopping-time density theorems ([Terras 1976](08-references.md#terras-1976), [Allouche 1979](08-references.md#allouche-1979)), nonexistence of 1-cycles ([Steiner 1977](08-references.md#steiner-1977)), and the beginning of computational verification.
|
||||
- **1985** — Jeffrey Lagarias publishes the first major survey, [Lagarias 1985](08-references.md#lagarias-1985), which remains the standard entry point; a research-volume follow-up appeared as [Lagarias 2010](08-references.md#lagarias-2010).
|
||||
- **2019–2022** — Terence Tao proves the strongest "almost all" result to date ([Tao 2022](08-references.md#tao-2022)).
|
||||
- **2026** — Still open. Verified computationally up to `2^71` ([04](04-computational-verification.md)); generalizations of the problem are provably undecidable ([06](06-generalizations.md)).
|
||||
|
||||
Paul Erdős, who offered a cash prize for a solution, famously remarked: *"Mathematics is not yet ready for such problems."* — first printed in [Lagarias 1985](08-references.md#lagarias-1985); its origin is conversational ([Lagarias 2010](08-references.md#lagarias-2010), preface).
|
||||
|
||||
## 1.4 Many names, one problem
|
||||
|
||||
The same iteration has circulated under several names: **3x+1 problem** (the standard modern name in the literature), **Collatz problem**, **Kakutani's problem**, **Ulam's problem**, **Syracuse problem**, **Hasse's algorithm**, **Thwaites conjecture**, and the **hailstone problem** (trajectories rise and fall like hailstones in a cloud).
|
||||
|
||||
## 1.5 Why the problem matters
|
||||
|
||||
- **Ultimate simplicity vs. depth.** The statement is understandable by a child, yet no known technique in number theory, ergodic theory, or logic resolves it.
|
||||
- **Arithmetic structure.** A proof would illuminate the interplay between the prime factorizations of `n` and of `n + 1`: the odd step `n ↦ 3n+1` mixes the 2-adic (parity) structure with multiplication by 3, and no invariant is known ([02](02-mathematical-foundations.md)).
|
||||
- **A proving ground.** The problem has driven methods in density theorems ([03](03-partial-results.md)), stochastic modeling ([05](05-heuristics.md)), Diophantine approximation (Baker's theorem), transfer operators, and formal verification ([07](07-open-problems.md)).
|
||||
- **A cautionary culture.** The problem attracts a steady stream of incorrect proofs; recognizing the recurring failure modes is part of the literature ([07](07-open-problems.md)). Richard Guy's *American Mathematical Monthly* column piece is literally titled *Don't try to solve these problems!* ([Guy 1983](08-references.md#guy-1983)). Lagarias calls it *"a really dangerous problem. People become obsessed with it"* ([Quanta 2019](08-references.md#quanta-2019)) and warned Alex Kontorovich: *"Don't fall into that trap"* ([Harper's 2025](08-references.md#harpers-2025)).
|
||||
- **A cultural footprint.** The conjecture lives in popular culture: xkcd no. 710 concludes that repeating the procedure long enough means *"eventually your friends will stop calling"* ([xkcd 710](08-references.md#xkcd-710)); xkcd no. 356 coined the term *nerd sniping* for the general phenomenon ([xkcd 356](08-references.md#xkcd-356)); JoAnne Growney's poem *A Mathematician's Nightmare* imagines a general store whose prices follow the rule — a beveled mirror priced at 27 dollars, *"shall I buy or wait for fifty-nine days until the price is lower?"* ([Growney 2006](08-references.md#growney-2006)).
|
||||
|
||||
## Navigation
|
||||
|
||||
| Next | Topic |
|
||||
|------|-------|
|
||||
| [02](02-mathematical-foundations.md) | Formal definitions and reformulations |
|
||||
| [03](03-partial-results.md) | Rigorous partial results |
|
||||
| [07](07-open-problems.md) | Open problems and status |
|
||||
@@ -0,0 +1,68 @@
|
||||
# 2. Mathematical Foundations
|
||||
|
||||
This file gives the formal vocabulary and the standard reformulations. Theorems build on it in [03-partial-results.md](03-partial-results.md); computational methods in [04-computational-verification.md](04-computational-verification.md).
|
||||
|
||||
## 2.1 Basic definitions
|
||||
|
||||
Let `C` be the Collatz map on the positive integers (Section 1.1). Write `C^k(n)` for the `k`-th iterate.
|
||||
|
||||
| Notion | Definition |
|
||||
|--------|------------|
|
||||
| **Trajectory / orbit** | The sequence `n, C(n), C²(n), …` |
|
||||
| **Stopping time** `σ(n)` | Least `k ≥ 0` with `C^k(n) < n`, or `∞` if none exists |
|
||||
| **Total stopping time** `τ(n)` | Least `k ≥ 0` with `C^k(n) = 1` |
|
||||
| **Maximum excursion** `M(n)` | `max_k C^k(n)` over the trajectory |
|
||||
| **Total stopping record** | `n` such that `τ(n) > τ(m)` for all `m < n` (27 is one: `τ(27) = 111`) |
|
||||
|
||||
**Proposition (descent equivalence).** The Collatz conjecture is equivalent to the statement that `σ(n) < ∞` for every `n`.
|
||||
*Reason:* if some iterate drops below `n`, then strong induction on `n` (all smaller starting values eventually reach 1) forces `τ(n) < ∞`; the converse is trivial. This equivalence is what makes "trajectories that dip below their start" the workhorse of verification (Section 4.1).
|
||||
|
||||
## 2.2 Standard reformulations
|
||||
|
||||
Each reformulation removes redundancy and is used by a different line of research.
|
||||
|
||||
### Shortcut (Syracuse) map
|
||||
|
||||
```
|
||||
T(n) = n/2 if n is even
|
||||
T(n) = (3n+1)/2 if n is odd
|
||||
```
|
||||
|
||||
Since `3n+1` is always even after an odd step, `T` follows the same orbits as `C` but with fewer steps. The conjecture for `C` is equivalent to the conjecture for `T`. Most analytic work uses `T` or the map below.
|
||||
|
||||
### Odd-only (accelerated) map
|
||||
|
||||
On odd `n ≥ 3` define
|
||||
|
||||
```
|
||||
U(n) = (3n+1) / 2^(v₂(3n+1))
|
||||
```
|
||||
|
||||
where `v₂(m)` is the exponent of 2 in `m` (the 2-adic valuation). `U` maps odd integers to odd integers, skipping the forced even steps. The conjecture is equivalent to: *every odd `n ≥ 3` reaches 1 under `U`.* In this picture each step multiplies by roughly `3/4` on average — the seed of the heuristic drift argument in [05-heuristics.md](05-heuristics.md).
|
||||
|
||||
### Parity vectors and the 2-adic extension
|
||||
|
||||
Encode a trajectory by its **parity vector**: the word over `{0,1}` recording even (0) / odd (1) at each step. Two facts make this encoding powerful:
|
||||
|
||||
1. The map `n ↦ (parity vector of n)` extends to a bijection `Q` from the 2-adic integers `ℤ₂` onto `ℤ₂` (the "parity vector map").
|
||||
2. Under `Q`, the shortcut map `T` becomes exactly the **shift map** on `ℤ₂` (drop the first 2-adic digit).
|
||||
|
||||
Consequences: `T` extends continuously to `ℤ₂`, is conjugate to a shift, is chaotic there, and its periodic points are dense in `ℤ₂`. But the positive integers form only a countable, measure-zero subset of `ℤ₂` — the ergodic description does **not** decide the conjecture; it explains the dynamics' complexity and underlies the transfer-operator viewpoint below. Attempts to convert this picture into a proof have all stalled — see [09](09-failed-attempts.md), Section 9.2.
|
||||
|
||||
### The inverse tree (Collatz graph)
|
||||
|
||||
The direct preimages of `m` under `C` are `2m` (always) and, if `m ≡ 4 (mod 6)`, also `(m−1)/3`. Rooted at the trivial cycle `{1, 2, 4}`, this defines the **inverse tree**. The conjecture is equivalent to: *the inverse tree contains every positive integer.* Verification algorithms exploit the same descent structure ([04](04-computational-verification.md)).
|
||||
|
||||
### Functional equations and transfer operators
|
||||
|
||||
[Berg and Meinardus 1994](08-references.md#berg-and-meinardus-1994) reformulate the conjecture via generating functions: it is equivalent to a statement about the solutions of certain functional equations, or equivalently about spectral properties (eigenvalues / spectral radius) of the associated Ruelle–Perron–Frobenius **transfer operator**. This connects the problem to dynamical-systems spectral theory; no proof has resulted so far — why this route stalls: [09](09-failed-attempts.md), Section 9.3.
|
||||
|
||||
### Tag systems
|
||||
|
||||
The parity-driven rewriting of the trajectory can be simulated by Post **tag systems**, and generalized Collatz maps are computationally universal ([06-generalizations.md](06-generalizations.md)). This is the bridge between the problem and logic/computability.
|
||||
|
||||
## 2.3 Arithmetic structure
|
||||
|
||||
- **Mixing of factorizations.** The odd step `n ↦ 3n+1 = 3(n+1) − 2` couples the factorization of `n` with that of `n+1` (an observation emphasized in [Barina 2020](08-references.md#barina-2020)). No classical multiplicative technique survives this coupling.
|
||||
- **Modular structure and density results.** The residue of `n` modulo `2^k` determines the first `k` parities of its trajectory up to an explicit affine adjustment. This is the mechanism behind the density theorems of [Terras 1976](08-references.md#terras-1976) and successors ([03](03-partial-results.md)).
|
||||
- **No known monovariant.** Every candidate potential function (log `n`, the odd part, heights, …) fails to be monotone along all orbits; there is no known quantity that strictly decreases at every step. This absence is the core obstacle ([07](07-open-problems.md)).
|
||||
@@ -0,0 +1,58 @@
|
||||
# 3. Rigorous Partial Results
|
||||
|
||||
All statements here are theorems with peer-reviewed proofs. Together they constrain *where* a counterexample could hide, but none reaches a full resolution — see [07-open-problems.md](07-open-problems.md) for what remains open. Notation (`σ`, `τ`, orbits) as in [02-mathematical-foundations.md](02-mathematical-foundations.md).
|
||||
|
||||
## 3.1 Almost all orbits descend
|
||||
|
||||
- **Theorem ([Terras 1976](08-references.md#terras-1976); independently [Everett 1977](08-references.md#everett-1977)).** The set of `n` with finite stopping time (`σ(n) < ∞`, i.e. the trajectory eventually drops below `n`) has natural density 1.
|
||||
*Method:* the residue of `n` mod `2^k` fixes the first `k` trajectory parities (up to an affine map); counting the residue classes that avoid any descent in `k` steps gives an exceptional density that tends to 0.
|
||||
- **[Allouche 1979](08-references.md#allouche-1979).** Extensions of the same method: for almost all `n`, the trajectory eventually falls below `n^θ` for suitable `θ < 1`.
|
||||
- **Theorem ([Korec 1994](08-references.md#korec-1994)).** For every `θ > log 3 / log 4 ≈ 0.7925`, almost all `n` have `C^k(n) < n^θ` for some `k`. This is the sharpest exponent obtainable by the modular-counting method.
|
||||
- **Theorem ([Krasikov and Lagarias 2003](08-references.md#krasikov-and-lagarias-2003)).** At least `x^0.84` integers in `[1, x]` eventually reach 1 — a counting lower bound on the verified set, independent of density language.
|
||||
|
||||
**Limitation common to all of these:** "almost all" leaves an exceptional set of density zero but *unbounded cardinality*. A counterexample could, as far as these theorems go, live in that exceptional set.
|
||||
|
||||
## 3.2 Almost bounded values — Tao
|
||||
|
||||
- **Theorem ([Tao 2022](08-references.md#tao-2022); preprint 2019).** Let `f : ℕ → ℕ` be *any* function with `f(n) → ∞` (e.g. `f(n) = log log n`). Then for almost all `n` — in the sense of **logarithmic density** — the minimum of the trajectory satisfies
|
||||
```
|
||||
min_k C^k(n) < f(n).
|
||||
```
|
||||
In words: almost all Collatz orbits attain *almost bounded* values. This subsumes and vastly strengthens Korec's exponent: the minimum is not merely below `n^0.7925` but below every divergent gauge.
|
||||
|
||||
*Method highlights:* an approximate transport/invariance property for a first-passage random variable of the Syracuse iteration, derived from estimates of the characteristic function of a skew random walk on the 3-adic cyclic group — the analytic formalization of the stochastic drift heuristics of [05-heuristics.md](05-heuristics.md).
|
||||
|
||||
*Obstacle:* the result **cannot** be pushed to a bounded `f` (which would nearly prove the conjecture). Logarithmic density is used because it has approximate multiplicative invariance; it still lacks true invariance under `T`, so the argument does not iterate downward to all `n` ([07](07-open-problems.md)).
|
||||
|
||||
## 3.3 Nonexistence of small cycles
|
||||
|
||||
A **cycle** is a periodic orbit; the trivial cycle is `{1, 4, 2}`. Following [Hercher 2023](08-references.md#hercher-2023), call a periodic orbit an **m-cycle** if it has `m` local minima (equivalently, `m` "up-crossings" between its odd steps). A nontrivial cycle must have `m ≥ 1`.
|
||||
|
||||
| Result | Statement | Tool |
|
||||
|--------|-----------|------|
|
||||
| [Steiner 1977](08-references.md#steiner-1977) | No nontrivial 1-cycles exist | Baker's theorem (linear forms in logarithms) + computation |
|
||||
| [Simons 2005](08-references.md#simons-and-de-weger-2005) | No nontrivial 2-cycles | refinements of the same method |
|
||||
| [Simons and de Weger 2005](08-references.md#simons-and-de-weger-2005) | No nontrivial m-cycles for `m ≤ 68` | Baker-type bounds, heavy computation |
|
||||
| [Hercher 2023](08-references.md#hercher-2023) | No nontrivial m-cycles for `m ≤ 91` | improved effective Baker bounds |
|
||||
|
||||
**Why Baker's theorem?** A cycle with `m` odd steps and `A` total halvings satisfies an exact relation of the form `2^A − 3^m·n = c` (with small `c` determined by the cycle's internal structure). Ruling out cycles requires sharp *lower* bounds for linear forms `A·log 2 − m·log 3 − log c`, which is precisely what Baker's theory provides. The effective constants weaken exponentially as `m` grows — hence the slow historical progress `1 → 2 → 68 → 91`.
|
||||
|
||||
**Combined with computation** (verified bound `2^71`, [04](04-computational-verification.md)): any nontrivial cycle would have to have **more than 91 local minima** and a **minimum element greater than `2^71 ≈ 2.36 × 10^21`**.
|
||||
|
||||
## 3.4 Divergent orbits
|
||||
|
||||
No divergent trajectory is known, and none has been ruled out. The density results of 3.1–3.2 do not exclude a divergent orbit (it would lie in the exceptional set), and the cycle results of 3.3 do not apply to unbounded orbits. The stochastic models of [05-heuristics.md](05-heuristics.md) predict divergence never occurs, but a proof is open ([07](07-open-problems.md)).
|
||||
|
||||
## 3.5 Summary of the known frontier
|
||||
|
||||
```
|
||||
Terras 1976 : σ(n) < ∞ for density-1 many n
|
||||
Allouche 1979 : below n^θ for suitable θ < 1, density-1 many
|
||||
Korec 1994 : below n^0.7925+ε density-1 many
|
||||
Krasikov–Lagarias : ≥ x^0.84 numbers ≤ x reach 1
|
||||
Tao 2022 : below any f(n) → ∞ for log-density-1 many n
|
||||
Steiner → Hercher : no nontrivial cycles with ≤ 91 local minima
|
||||
Computation : all n ≤ 2^71 converge (Barina project)
|
||||
```
|
||||
|
||||
What is *not* covered by any theorem: a proof for all `n`, the existence/nonexistence of cycles with `m > 91`, and the existence/nonexistence of divergent orbits.
|
||||
@@ -0,0 +1,44 @@
|
||||
# 4. Computational Verification
|
||||
|
||||
Computation cannot prove the conjecture, but every new verified bound raises the floor beneath any hypothetical counterexample and feeds directly into the theoretical constraints ([03-partial-results.md](03-partial-results.md), Section 3.3).
|
||||
|
||||
## 4.1 What "verified up to N" means
|
||||
|
||||
A project verifies the conjecture up to `N` when it has shown that **every** `n ≤ N` eventually reaches 1. The descent equivalence ([02](02-mathematical-foundations.md), Section 2.1) makes this far cheaper than it sounds:
|
||||
|
||||
> A single trajectory that dips **below its own starting value** certifies, by strong induction, every member of that trajectory — and more, by the induction structure below it.
|
||||
|
||||
Consequently only starting values whose trajectories stay *above* themselves for long require actual iteration. Standard implementations:
|
||||
|
||||
1. Partition `[1, N]` into intervals; iterate each trajectory only until it falls below the interval's lower bound.
|
||||
2. Prune with residue classes: from the modular structure ([02](02-mathematical-foundations.md), Section 2.3), whole arithmetic progressions can be certified or eliminated at once; only candidates in a thinning sieve of classes mod `2^k` need work.
|
||||
3. Represent states as dense bitsets; accelerate the inner loop with SIMD (AVX) on CPUs and GPU kernels.
|
||||
4. Distribute the interval tasks over many volunteer machines.
|
||||
|
||||
## 4.2 The Barina project — state of the art
|
||||
|
||||
The record-holding effort is the distributed verification project of **David Barina** (Brno University of Technology), running with volunteer clients since 2017 ([Barina project](08-references.md#barina-project)):
|
||||
|
||||
| Year | Verified bound | Value | Source |
|
||||
|------|----------------|-------|--------|
|
||||
| 2020 | `2^68` | ≈ 2.95 × 10^20 | [Barina 2020](08-references.md#barina-2020) |
|
||||
| 2025/26 | `2^71` | ≈ 2.36 × 10^21 | [Barina 2025](08-references.md#barina-2025) |
|
||||
|
||||
The papers document the sieve-based pruning, dense data structures, SIMD/GPU acceleration, and the distributed task management sketched in 4.1, with a total speedup of orders of magnitude over naive iteration.
|
||||
|
||||
Earlier milestones by other authors (Crays in the 1980s, distributed efforts in the 1990s–2010s) were successively superseded; Barina's project has held the record since 2017 and continues to run. Independent record-keeping of *trajectory statistics* (distinct from a verified bound) is maintained by the community — see 4.4.
|
||||
|
||||
## 4.3 What verification cannot do
|
||||
|
||||
- **No structural upper bound on a counterexample is known.** Nothing in the theory suggests a counterexample (if one exists) must be near `2^71` — heuristic models ([05](05-heuristics.md)) in fact suggest counterexamples, should they exist, would be "exotic" outliers, not small numbers.
|
||||
- **Verification is not proof.** The conjecture quantifies over all positive integers; computation covers an initial segment only.
|
||||
- **Still, it has teeth.** Each bound converts into hard constraints: every nontrivial cycle must have minimum > `2^71` ([03](03-partial-results.md), Section 3.3), and any "small counterexample" folklore claims are thereby dead.
|
||||
|
||||
## 4.4 Records and databases
|
||||
|
||||
- **Roosendaal's database** ([Roosendaal records](08-references.md#roosendaal-records)) tracks community-computed records: largest total stopping times (`τ`), largest maximum excursions (`M`), path records per interval. The classic benchmark values are `τ(27) = 111`, `M(27) = 9232`; early delay-record holders, all long verified, include `τ(871) = 178`, `τ(6171) = 261`, `τ(77031) = 350`, and `τ(837799) = 524` ([OEIS delay records](08-references.md#oeis-delay-records)); today's record holders are astronomically larger.
|
||||
- **Large-scale experimental studies** continue, including 2026 preprints reporting on the order of `10^14` computed trajectories with hundreds of derived structural observations ([arXiv 2603.11066](08-references.md#arxiv-260311066)). Note: preprint, not peer-reviewed.
|
||||
|
||||
## 4.5 Verification culture
|
||||
|
||||
Because claimed proofs and claimed disproofs appear constantly ([07](07-open-problems.md), Section 7.3), the computational community treats artifacts as evidence only when they are reproducible: distributed, independently re-runnable, and — increasingly — cross-checked with formal proof assistants. The limits of that trust were demonstrated by the 2026 Lean kernel-bug incident ([07](07-open-problems.md), Section 7.3).
|
||||
@@ -0,0 +1,55 @@
|
||||
# 5. Heuristic and Stochastic Models
|
||||
|
||||
*Everything in this file is heuristic — a model, not a theorem — except where it explicitly cites a rigorous result. The heuristics nonetheless organize the field's expectations and motivate the strongest theorems ([03-partial-results.md](03-partial-results.md)).*
|
||||
|
||||
## 5.1 The random-parity model
|
||||
|
||||
The odd step `n ↦ 3n+1` always yields an even number, so parities along a trajectory are *not* independent in a naive sense — but after removing the forced even steps ([02](02-mathematical-foundations.md), Section 2.2), the standard model treats the parity sequence as independent fair coin flips.
|
||||
|
||||
Under that model, one shortcut step multiplies `n` by
|
||||
|
||||
```
|
||||
1/2 with probability 1/2 (even step)
|
||||
3/2 with probability 1/2 (odd step: (3n+1)/2 ≈ (3/2)n)
|
||||
```
|
||||
|
||||
so the expected change in `log n` per step is
|
||||
|
||||
```
|
||||
E[Δ log n] = ½·log(1/2) + ½·log(3/2) = ½·log(3/4) ≈ −0.1438
|
||||
```
|
||||
|
||||
i.e. a typical trajectory shrinks by a factor `e^{−0.1438} ≈ 0.866` per step. Inverting the drift gives the classical heuristic prediction
|
||||
|
||||
```
|
||||
expected total stopping time τ(n) ≈ 6.95 · ln n
|
||||
```
|
||||
|
||||
Sanity checks: powers of two (`τ(2^k) = k`) are *fast* outliers relative to the typical `≈ 4.8·k`; `τ(27) = 111` versus the typical prediction `6.95 · ln 27 ≈ 23` marks 27 as a *slow* outlier — records are exactly such outliers.
|
||||
|
||||
## 5.2 Fluctuations, excursions, and records
|
||||
|
||||
A multiplicative random walk with negative drift still makes large upward excursions. In the branching-random-walk model of [Lagarias and Weiss 1992](08-references.md#lagarias-and-weiss-1992), the record values of the total stopping time over `n ≤ x` grow like
|
||||
|
||||
```
|
||||
max_{n ≤ x} τ(n) ≈ β_max · ln x, β_max ≈ 41.68
|
||||
```
|
||||
|
||||
a heuristic constant that matches the observed record data remarkably well. The same model predicts the observed heavy-tailed distribution of maximum excursions `M(n)` — the "hailstone" behavior that gives the problem one of its names.
|
||||
|
||||
## 5.3 What the models say about the three escape routes
|
||||
|
||||
| Scenario | Model verdict | Rigorous status |
|
||||
|----------|---------------|-----------------|
|
||||
| Divergent orbit | Probability 0 (negative drift) | Not ruled out ([03](03-partial-results.md), 3.4) |
|
||||
| Nontrivial cycle | Probability 0 in the model | Excluded only for ≤ 91 minima ([03](03-partial-results.md), 3.3) |
|
||||
| Convergence for all n | Expected (typical behavior) | Known only for density-1 sets ([03](03-partial-results.md), 3.1–3.2) |
|
||||
|
||||
## 5.4 Why heuristics cannot close the problem
|
||||
|
||||
Stochastic arguments have two fundamental gaps:
|
||||
|
||||
1. **Exceptional sets are real.** Every rigorous "almost all" theorem leaves a density-zero exceptional set of unbounded cardinality, and a single counterexample lives exactly there. Probabilistic reasoning assigns such outliers vanishing *measure*, but a proof must exclude them *one by one*.
|
||||
2. **Independence is assumed, not proven.** The model's coin flips are an idealization; the actual parity sequence is deterministic and entangled with the arithmetic of `3n+1`. History is full of arguments that silently promoted the heuristic independence to a proof ([07](07-open-problems.md), Section 7.2).
|
||||
|
||||
**Best current interpretation:** Tao's theorem ([Tao 2022](08-references.md#tao-2022)) is precisely the rigorous fragment of this heuristic — the negative-drift argument made analytic, valid for almost all `n` — while the passage from "almost all" to "all" is exactly the part the model cannot supply.
|
||||
@@ -0,0 +1,48 @@
|
||||
# 6. Generalizations and Related Problems
|
||||
|
||||
Loosening the Collatz map destroys the conjecture's luck — and in the general case, provably so. Notation as in [02-mathematical-foundations.md](02-mathematical-foundations.md).
|
||||
|
||||
## 6.1 The map over all integers ℤ
|
||||
|
||||
Run the same rule `C(n) = n/2` (even), `3n+1` (odd) on negative integers. Three periodic orbits are known besides the trivial one:
|
||||
|
||||
```
|
||||
{ −1, −2 }
|
||||
{ −5, −14, −7, −20, −10 }
|
||||
{ −17, −50, −25, −74, −37, −110, −55, −164, −82, −41,
|
||||
−122, −61, −182, −91, −272, −136, −68, −34 } (18 elements)
|
||||
```
|
||||
|
||||
Substituting `n ↦ −n` shows that `3x+1` on the negative integers is exactly the **3x−1 problem** on the positive integers (for odd `n`, `C(−n) = −(3n−1)`). The standard conjecture for `ℤ` is that the three cycles above are the only nontrivial ones — also unproven.
|
||||
|
||||
## 6.2 The kx+1 family
|
||||
|
||||
Define `C_k(n) = n/2` (even), `k·n + 1` (odd), for odd `k ≥ 1`. The drift heuristic ([05](05-heuristics.md), Section 5.1) computes the geometric mean of the step multipliers `1/2` and `k/2` as `√k / 2`:
|
||||
|
||||
- `k = 1` — trivial descent.
|
||||
- `k = 3` — **the Collatz case**: geometric drift `√3/2 < 1`, the unique nontrivial `k` with expected downward drift. This "borderline" position is widely suspected to be why `3n+1` is exactly hard enough to be unsolved.
|
||||
- `k ≥ 5` — expected upward drift, and the dynamics confirm it:
|
||||
|
||||
**5x+1** has known nontrivial cycles
|
||||
|
||||
```
|
||||
{ 13, 66, 33, 166, 83, 416, 208, 104, 52, 26 }
|
||||
{ 17, 86, 43, 216, 108, 54, 27, 136, 68, 34 }
|
||||
```
|
||||
|
||||
and orbits, e.g. starting at 7, that grow without apparent bound in all computations (believed divergent, unproven). So *both* failure modes that the Collatz conjecture rules out — extra cycles and divergence — actually occur for `k = 5`.
|
||||
|
||||
## 6.3 Generalized Collatz maps and undecidability
|
||||
|
||||
A **generalized Collatz map** is a piecewise-affine map on the integers: fix a modulus `d` and, for each residue class `i`, a linear function `T(n) = a_i·n + b_i` applied when `n ≡ i (mod d)`. The 3x+1 map is the case `d = 2`.
|
||||
|
||||
- **Theorem (Conway).** [Conway 1972](08-references.md#conway-1972) proved this class is *computationally universal*: generalized Collatz maps can simulate arbitrary computation, and there is **no algorithm** that, given a generalized Collatz map, decides whether every orbit reaches 1. Conway later distilled the mechanism into the esoteric language **FRACTRAN** ([Conway 1987](08-references.md#conway-1987)), whose programs are exactly generalized Collatz-type iterations (his `PRIMEGAME` computes the primes).
|
||||
- **Theorem ([Kurtz and Simon 2007](08-references.md#kurtz-and-simon-2007)).** A *natural* generalization — very close to 3x+1 — has a totality problem that is **Π⁰₂-complete** in the arithmetical hierarchy: deciding whether all orbits converge is as hard as deciding totality questions for programs in general, i.e. algorithmically undecidable.
|
||||
|
||||
**Crucial nuance.** Undecidability results apply to *families* of maps. They do **not** show that the single map `3n+1` is undecidable, and they do not settle the conjecture. What they destroy is the hope for a *uniform* technique that would treat all such maps at once — and they explain why naive "I found a monotone-modular argument" proofs keep failing ([07](07-open-problems.md), Section 7.2).
|
||||
|
||||
## 6.4 Continuous and p-adic extensions
|
||||
|
||||
- **2-adic dynamics.** `T` extends to the 2-adic integers and is conjugate to the shift map ([02](02-mathematical-foundations.md), Section 2.2) — a complete, but non-decisive, dynamical description.
|
||||
- **Analytic reformulations.** The transfer-operator / functional-equation program of [Berg and Meinardus 1994](08-references.md#berg-and-meinardus-1994) recasts the conjecture as a spectral statement; related approaches study Collatz-type maps on the reals (piecewise-linear extensions) and complex interpolations. None has yielded a proof; see [09](09-failed-attempts.md), Sections 9.3 and 9.9, for where these routes stall.
|
||||
- **3-adic structure.** The odd step's multiplication by 3 introduces genuinely 3-adic phenomena (visible in Tao's proof, [03](03-partial-results.md), Section 3.2); the tension between the 2-adic and 3-adic pictures is a recurring theme ([07](07-open-problems.md)).
|
||||
@@ -0,0 +1,38 @@
|
||||
# 7. Open Problems and Current Status
|
||||
|
||||
Status as of **August 2026**: the Collatz conjecture is **open**. This file collects what is genuinely unknown, why the problem resists attack, and the current state of play. Rigorous groundwork is in [03-partial-results.md](03-partial-results.md) and [06-generalizations.md](06-generalizations.md).
|
||||
|
||||
## 7.1 The three outstanding questions
|
||||
|
||||
1. **Convergence.** Does every positive integer reach 1? (The conjecture itself.)
|
||||
Known: all `n ≤ 2^71` converge ([04](04-computational-verification.md)); density-1 many `n` descend arbitrarily far ([03](03-partial-results.md), 3.1–3.2).
|
||||
2. **Nontrivial cycles.** Does a periodic orbit other than `{1, 4, 2}` exist?
|
||||
Known: excluded for cycles with ≤ 91 local minima ([03](03-partial-results.md), 3.3); any nontrivial cycle would have minimum > `2^71`.
|
||||
3. **Divergent orbits.** Does any trajectory grow without bound?
|
||||
Known: none found; heuristics predict none ([05](05-heuristics.md)); no theorem excludes one.
|
||||
|
||||
These exhaust the failure modes: a counterexample is either a cycle or divergent.
|
||||
|
||||
## 7.2 Why the problem is so hard
|
||||
|
||||
- **No monovariant.** No known quantity strictly decreases along every orbit ([02](02-mathematical-foundations.md), Section 2.3). Every descent-style proof strategy needs one.
|
||||
- **2-adic ↔ 3-adic mixing.** The map entangles parity structure (mod `2^k`) with multiplication by 3. Techniques that control one scale lose the other. Baker's theorem handles the tension only for cycles — with bounds that weaken exponentially in the cycle length, which is why the cycle frontier creeps forward `1 → 2 → 68 → 91` ([03](03-partial-results.md), 3.3).
|
||||
- **Undecidability of the neighborhood.** Conway's undecidability result and the Π⁰₂-completeness of the natural generalization ([06](06-generalizations.md), 6.3) prove that no uniform algorithm resolves the *family* of generalized Collatz maps. This does not doom the single map, but it rules out entire classes of "uniform modular" arguments and keeps proving that the usual suspects fail.
|
||||
- **The "almost all" plateau.** Tao's method ([03](03-partial-results.md), 3.2) formalizes the stochastic drift for almost all `n`, but logarithmic density lacks invariance under the map, so the argument cannot iterate down to *all* `n`. No known route crosses from density-1 statements to a complete proof.
|
||||
- **The heuristics–proof gap.** Stochastic models ([05](05-heuristics.md)) predict the answer confidently, yet cannot exclude a single exotic outlier — and the literature documents recurring failure modes in attempted proofs: promoting heuristic independence to proof, misapplied modular arguments, and Baker-bound sign errors (documented in [Lagarias 1985](08-references.md#lagarias-1985) and [Lagarias 2010](08-references.md#lagarias-2010); detailed case studies in [09](09-failed-attempts.md)).
|
||||
|
||||
## 7.3 Status 2026
|
||||
|
||||
- **No accepted proof.** Preprints claiming a proof appear regularly (e.g. a February 2025 fixed-point-theorem attempt on arXiv, [arXiv 2502.20642](08-references.md#claimed-proof-2025)); none has been accepted by the mathematical community.
|
||||
- **Verification frontier:** `2^71` and climbing ([Barina 2025](08-references.md#barina-2025)).
|
||||
- **The July 2026 formal-methods incident.** An AI-assisted "disproof" of the Collatz conjecture was released on 25 July 2026 and *type-checked in Lean* — but it exploited **two soundness bugs in Lean's kernel** (tracked as issue #14576, involving nested inductive types; a second bug hit an external checker). The bugs were patched within hours ([Lean kernel incident 2026](08-references.md#lean-kernel-incident-2026)). Lessons drawn by the community: (i) proof assistants remain the strongest backstop against computational fallacy; (ii) verifier soundness is itself a research target, and "it type-checks" demands independent re-verification for extraordinary claims.
|
||||
- **Prizes** (for a proof or counterexample, under the respective terms): **¥120,000,000** offered by Bakuage in 2017 ([Bakuage prize](08-references.md#bakuage-prize)); **$50** by H. S. M. Coxeter ([Coxeter 1971](08-references.md#coxeter-1971)); **$500** by Paul Erdős; **£1000** by Bryan Thwaites ([Lagarias 1985](08-references.md#lagarias-1985)).
|
||||
|
||||
## 7.4 Where progress could come from
|
||||
|
||||
Directions actively discussed in the literature (possibilities, not predictions):
|
||||
|
||||
- **Sharper Baker bounds** to push cycle exclusion beyond `m = 91` ([03](03-partial-results.md), 3.3).
|
||||
- **Analytic number theory / spectral theory**: strengthening Tao-type results; spectral analysis of the transfer operator ([02](02-mathematical-foundations.md), [06](06-generalizations.md), 6.4).
|
||||
- **Formal verification** of partial results and of the verification software itself ([04](04-computational-verification.md), 4.5).
|
||||
- **Cross-fertilization** with the decidability/complexity picture of generalized maps ([06](06-generalizations.md), 6.3).
|
||||
@@ -0,0 +1,192 @@
|
||||
# 8. References
|
||||
|
||||
Central bibliography. All other documentation files cite entries here by author-year anchor; URLs appear only in this file.
|
||||
|
||||
## Primary research papers
|
||||
|
||||
### Terras 1976
|
||||
R. Terras, *A stopping time problem on the positive integers*, Acta Arithmetica 30 (1976), 241–252. — Stopping time finite for natural-density-1 many `n`. (Print; see also [Lagarias 1985](#lagarias-1985) for a survey account.)
|
||||
|
||||
### Everett 1977
|
||||
C. J. Everett, *Iteration of the number-theoretic function f(2n) = n, f(2n+1) = 3n+2*, Advances in Mathematics 25 (1977), 42–45. — Independent proof of the Terras density result. (Print.)
|
||||
|
||||
### Steiner 1977
|
||||
R. P. Steiner, *A theorem on the Syracuse problem*, Acta Arithmetica 33 (1977), 135–141. — No nontrivial 1-cycles; first application of Baker's theorem to the problem. (Print.)
|
||||
|
||||
### Allouche 1979
|
||||
J.-P. Allouche, *Sur la conjecture de "Syracuse"*, Journal of Number Theory 12 (1979), 476–478. — Density extensions to below-`n^θ` descent. (Print.)
|
||||
|
||||
### Korec 1994
|
||||
I. Korec, *A density estimate for the `3x+1` problem*, Mathematica Slovaca 44 (1994), 85–89. — Almost all orbits fall below `n^θ` for `θ > log 3/log 4 ≈ 0.7925`. (Print.)
|
||||
|
||||
### Krasikov and Lagarias 2003
|
||||
I. Krasikov, J. C. Lagarias, *Bounds for the `3x+1` problem using difference inequalities*, Acta Arithmetica 109 (2003), 237–258. — At least `x^0.84` integers below `x` reach 1. (Print.)
|
||||
|
||||
### Simons and de Weger 2005
|
||||
S. Simons, B. de Weger, *Theoretical and computational bounds for m-cycles of the `3n+1` problem*, Acta Arithmetica 117 (2005), 51–70. — No nontrivial m-cycles for `m ≤ 68` (building on S. Simons's 2005 2-cycle result). (Print.)
|
||||
|
||||
### Hercher 2023
|
||||
C. Hercher, *There are no Collatz m-cycles with m ≤ 91*, Journal of Integer Sequences 26 (2023), Article 23.3.5.
|
||||
- Paper: <https://cs.uwaterloo.ca/journals/JIS//VOL26/Hercher/hercher5.html>
|
||||
- Preprint: <https://arxiv.org/abs/2201.00406>
|
||||
|
||||
### Tao 2022
|
||||
T. Tao, *Almost all orbits of the Collatz map attain almost bounded values*, Forum of Mathematics, Pi 10 (2022), e12.
|
||||
- Paper: <https://www.cambridge.org/core/journals/forum-of-mathematics-pi/article/almost-all-orbits-of-the-collatz-map-attain-almost-bounded-values/1008CC2DF91AF87F66D190C5E01C907F>
|
||||
- Preprint: <https://arxiv.org/abs/1909.03562>
|
||||
- Author's blog exposition: <https://terrytao.wordpress.com/2019/09/10/almost-all-collatz-orbits-attain-almost-bounded-values/>
|
||||
|
||||
## Surveys and books
|
||||
|
||||
### Lagarias 1985
|
||||
J. C. Lagarias, *The `3x+1` problem and its generalizations*, American Mathematical Monthly 92 (1985), 3–23. — The classic survey: history, folklore, partial results, recurring proof failures. (Print; widely available in reprints.)
|
||||
|
||||
### Lagarias 2010
|
||||
J. C. Lagarias (ed.), *The Ultimate Challenge: The `3x+1` Problem*, American Mathematical Society, 2010. — Research-level collection of surveys. (Print.)
|
||||
|
||||
### Coxeter 1971
|
||||
H. S. M. Coxeter, *Cyclic sequences and frieze patterns: The Fourth Felix Behrend Memorial Lecture*, Vinculum 8 (1971), 4–7. — Written version of a 1970 lecture; per the preface of [Lagarias 2010](#lagarias-2010) the earliest published paper explicitly stating the `3x+1` problem, presented there as "mathematical gossip" with a **$50 prize**. (Print.)
|
||||
|
||||
### Collatz 1986
|
||||
L. Collatz, *On the motivation and origin of the (3n+1) problem* (Chinese), Journal of Qufu Normal University, Natural Science Edition 12 (1986), no. 3, 9–11. — Based on a talk at Qufu Normal University; the only paper by Collatz discussing his work on the problem. English translation included in [Lagarias 2010](#lagarias-2010). (Print.)
|
||||
|
||||
### Berg and Meinardus 1994
|
||||
L. Berg, G. Meinardus, *Functional equations connected with the Collatz problem*, Results in Mathematics 25 (1994), 1–12. — Functional-equation/transfer-operator reformulation. (Print.)
|
||||
|
||||
### Lagarias and Weiss 1992
|
||||
J. C. Lagarias, A. Weiss, *The `3x+1` problem: two stochastic models*, Annals of Applied Probability 2 (1992), 229–261. — Branching-random-walk model; record constant `β_max ≈ 41.68`. (Print.)
|
||||
|
||||
## Computational verification
|
||||
|
||||
### Barina 2020
|
||||
D. Barina, *Convergence verification of the Collatz problem*, The Journal of Supercomputing 77 (2021), 2681–2688 (online 01 July 2020).
|
||||
- <https://link.springer.com/article/10.1007/s11227-020-03368-x>
|
||||
- Verified bound: `2^68`.
|
||||
- Bibliography corrected 2026-08-29 (volume/year/pages) per the Springer article page and the Barina project page (<https://pcbarina.fit.vut.cz/>); previously listed as "76 (2020), 9678–9696".
|
||||
|
||||
### Barina 2025
|
||||
D. Barina, *Improved verification limit for the convergence of the Collatz problem*, The Journal of Supercomputing (2025/2026).
|
||||
- <https://link.springer.com/article/10.1007/s11227-025-07337-0>
|
||||
- Verified bound: `2^71` — current record.
|
||||
|
||||
### Barina project
|
||||
D. Barina, *Convergence verification of the Collatz problem* — the live distributed-computing project.
|
||||
- <https://pcbarina.fit.vut.cz/>
|
||||
|
||||
### Roosendaal records
|
||||
E. Roosendaal, *On the `3x+1` conjecture* — community database of trajectory records (delays, maxima, path records).
|
||||
- <https://www.ericr.nl/wondrous/index.html>
|
||||
|
||||
### OEIS delay records
|
||||
OEIS A006877 (starting values that set new records for total stopping time) and A006878 (the corresponding record values), derived from [Roosendaal records](#roosendaal-records).
|
||||
- <https://oeis.org/A006877>
|
||||
- <https://oeis.org/A006878>
|
||||
|
||||
### arXiv 2603.11066
|
||||
*Exploring Collatz dynamics with human-LLM collaboration* (preprint, 2026). — Large-scale computational study (`~10^14` trajectories, ~630 derived structural results). **Not peer-reviewed.**
|
||||
- <https://arxiv.org/abs/2603.11066>
|
||||
|
||||
## Generalizations and undecidability
|
||||
|
||||
### Conway 1972
|
||||
J. H. Conway, *Unpredictable iterations*, Proceedings of the 1972 Number Theory Conference, University of Colorado, Boulder (1972), 49–52. — Generalized Collatz maps are computationally universal; totality undecidable. (Print.)
|
||||
|
||||
### Conway 1987
|
||||
J. H. Conway, *Fractran: a simple universal programming language for arithmetic*, in: Open Problems in Communication and Computation, Springer, 1987, 4–26. (Print.)
|
||||
|
||||
### Kurtz and Simon 2007
|
||||
S. A. Kurtz, J. Simon, *The undecidability of the generalized Collatz problem*, STACS 2007, LNCS 4484, Springer, 542–553. — Natural generalization is Π⁰₂-complete.
|
||||
- <https://people.cs.uchicago.edu/~simon/RES/collatz.pdf>
|
||||
|
||||
## Failed and stalled attempts
|
||||
|
||||
### Lagarias bibliography 2003
|
||||
J. C. Lagarias, *The `3x+1` problem: An annotated bibliography (1963–1999)*, arXiv:math/0309224. — Catalogues the attempted-proof literature and its recurring errors.
|
||||
- <https://arxiv.org/abs/math/0309224>
|
||||
|
||||
### Lagarias bibliography 2006
|
||||
J. C. Lagarias, *The `3x+1` problem: An annotated bibliography, II (2000–2009)*, arXiv:math/0608208. — Sequel covering 2000–2009.
|
||||
- <https://arxiv.org/abs/math/0608208>
|
||||
|
||||
### Bernstein 1994
|
||||
D. J. Bernstein, *A non-iterative 2-adic statement of the `3n+1` conjecture*, Proceedings of the American Mathematical Society 121, no. 2 (1994).
|
||||
- <https://www.ams.org/proc/1994-121-02/S0002-9939-1994-1186982-9/>
|
||||
- PDF: <https://pure.tue.nl/ws/portalfiles/portal/3370267/Metis219674.pdf>
|
||||
|
||||
### Opfer 2011
|
||||
G. Opfer, *An analytic approach to the Collatz `3n+1` problem*, Hamburger Beiträge zur Angewandten Mathematik, Preprint 2011-09 (May 2011). — Withdrawn via the author's own note after the central covering claim was found incomplete.
|
||||
- <https://preprint.math.uni-hamburg.de/public/papers/hbam/hbam2011-09.pdf>
|
||||
|
||||
### de Weger 2011
|
||||
B. M. M. de Weger, *Comments on Opfer's alleged proof of the `3n+1` conjecture* (2011). — Independent technical refutation.
|
||||
- <https://math.deweger.net/reports/%5B2011%5DOpfer.pdf>
|
||||
|
||||
### Mahler 1968
|
||||
K. Mahler, *An unsolved problem on the powers of 3/2*, Journal of the Australian Mathematical Society 8 (1968), 129–142. — The Z-numbers problem. (Print.)
|
||||
|
||||
### Flatto, Lagarias, Pollington 1995
|
||||
L. Flatto, J. C. Lagarias, A. D. Pollington, *On the range of fractional parts `{ξ(p/q)^n}`*, Acta Arithmetica 70 (1995), 125–147. — Partial results on Z-numbers. (Print.)
|
||||
|
||||
## Claims to treat with caution
|
||||
|
||||
### Claimed proof 2025
|
||||
*On a fixed point theorem and a proof of the Collatz conjecture* (arXiv preprint, Feb 2025) — **not accepted by the mathematical community**; cited here only as an example of the recurring claimed-proof genre ([07](07-open-problems.md), 7.3).
|
||||
- <https://arxiv.org/abs/2502.20642>
|
||||
|
||||
### Community literature review 2026
|
||||
B. Smyth, *Collatz literature review* (2026) — an annotated community review of the state of the art, including the cycle-results chain.
|
||||
- <https://github.com/barrysmyth/collatz_2026/blob/main/collatz-literature-review.md>
|
||||
|
||||
## Formal-methods incident (2026)
|
||||
|
||||
### Lean kernel incident 2026
|
||||
The AI-assisted Lean "disproof" of 25 July 2026, invalidated by two Lean kernel soundness bugs (issue #14576, nested inductive types; patched in PR #14577):
|
||||
- Technical postmortem: <https://mindpattern.ai/s/2026-07-31-an-ai-generated-lean-proof-of-collatz-verified-by-exploiting-two-separate-kernel-soun>
|
||||
- Bug #14576 analysis and fix: <https://aitoolly.com/ai-news/article/2026-08-02-lean-kernel-soundness-bug-14576-postmortem-of-the-ai-assisted-collatz-conjecture-disproof-and-fix>
|
||||
- News coverage: <https://gigazine.net/gsc_news/en/20260803-collatz-lean-kernel-bug>
|
||||
|
||||
## Popular and cultural sources
|
||||
|
||||
### Guy 1983
|
||||
R. K. Guy, *Don't try to solve these problems!*, American Mathematical Monthly 90 (1983), 35–41. — Expository piece for the *Unsolved Problems* column; a potpourri of `3x+1`-like problems including the original one. Per [Lagarias 2010](#lagarias-2010): none of the four problems formulated there has been solved. (Print.)
|
||||
|
||||
### Quanta 2019
|
||||
K. Hartnett, *Mathematician proves huge result on 'dangerous' problem*, Quanta Magazine, 11 December 2019. — Source of Lagarias's characterization: *"This is a really dangerous problem. People become obsessed with it and it really is impossible."*
|
||||
- <https://www.quantamagazine.org/mathematician-proves-huge-result-on-dangerous-problem-20191211/>
|
||||
|
||||
### Harper's 2025
|
||||
J. Kloc, *The Dangerous Problem*, Harper's Magazine, February 2025. — Essay on the conjecture's cultural pull; source of the Kontorovich anecdote (Lagarias: *"Don't fall into that trap"* — ignored).
|
||||
- <https://harpers.org/archive/2025/02/the-dangerous-problem-collatz-conjecture-joe-kloc/>
|
||||
|
||||
### Growney 2006
|
||||
J. Growney, *A Mathematician's Nightmare*, poem, in: *My Dance is Mathematics* (Paper Kite Press, 2006); blog version 2011. — A general store whose prices follow the Collatz rule in shortcut form `(3n+1)/2`; a mirror priced at 27 dollars — *"shall I buy or wait for fifty-nine days until the price is lower?"*
|
||||
- Blog post: <https://poetrywithmathematics.blogspot.com/2011/03/nightmare-of-unsolved-problem.html>
|
||||
- Chapbook page: <https://joannegrowney.com/ChapbookMyDance.html>
|
||||
|
||||
### xkcd 710
|
||||
R. Munroe, *Collatz Conjecture*, xkcd no. 710. — Caption: *"...you repeat this procedure long enough, eventually your friends will stop calling to see if you want to hang out."* Title text: *"The Strong Collatz Conjecture states that this holds for any set of obsessively-hand-applied rules."*
|
||||
- <https://xkcd.com/710/>
|
||||
|
||||
### xkcd 356
|
||||
R. Munroe, *Nerd Sniping*, xkcd no. 356. — *"There's a certain type of brain that's easily disabled. If you show it an interesting problem, it involuntarily drops everything else to work on it."* (General phenomenon, not Collatz-specific.)
|
||||
- <https://xkcd.com/356/>
|
||||
|
||||
### Veritasium 2021
|
||||
D. Muller, *The Simplest Math Problem No One Can Solve*, Veritasium (YouTube), 2021. — Major popularization (27, hailstones, inverse tree; states the then-current `2^68` bound). Narrative texture only, not a research source.
|
||||
- <https://www.youtube.com/watch?v=094y1Z2wpJg>
|
||||
|
||||
### Numberphile (Eisenbud)
|
||||
D. Eisenbud, *UNCRACKABLE? The Collatz Conjecture*, Numberphile (YouTube). — Popular introduction. Narrative texture only, not a research source.
|
||||
- <https://www.youtube.com/watch?v=5mFpVDpKX70>
|
||||
|
||||
### CECM Lagarias 1985 site
|
||||
HTML edition of [Lagarias 1985](#lagarias-1985) (Simon Fraser University, CECM), including images of a two-page letter in which Collatz claims priority (courtesy of Mike Mays).
|
||||
- <https://www.cecm.sfu.ca/organics/papers/lagarias/paper/html/paper.html>
|
||||
|
||||
## Prizes
|
||||
|
||||
### Bakuage prize
|
||||
Bakuage Co., Ltd., *120 Million JPY Collatz Conjecture Prize* (announced 2017, for a proof or counterexample under the stated terms).
|
||||
- <https://www.bakuage.com/en/prize>
|
||||
|
||||
Further historical prizes are anecdotal but printed in [Lagarias 1985](#lagarias-1985): **$50** (Coxeter, 1970 — see [Coxeter 1971](#coxeter-1971)), **$500** (Erdős), **£1000** (Thwaites). The Erdős remark's origin is conversational ([Lagarias 2010](#lagarias-2010), preface). See [07](07-open-problems.md), 7.3.
|
||||
@@ -0,0 +1,66 @@
|
||||
# 9. Failed and Stalled Proof Attempts
|
||||
|
||||
This file documents **substantial** attempts only: approaches with genuine mathematical machinery, identifiable authorship, and either a documented refutation or a rigorously identified barrier. Routine erroneous attempts — hundreds exist, catalogued in the annotated bibliographies of [Lagarias bibliography 2003](08-references.md#lagarias-bibliography-2003) and [Lagarias bibliography 2006](08-references.md#lagarias-bibliography-2006) — are represented once, as the dominant archetype (Section 9.1). Attempts are classified as **failed** (refuted) or **stalled** (no known way forward). The rigorous results these attempts fell short of are in [03-partial-results.md](03-partial-results.md); current status in [07-open-problems.md](07-open-problems.md).
|
||||
|
||||
## 9.1 The "lost classes" archetype — modular induction pushed too far
|
||||
|
||||
- **Approach.** Terras's method ([03](03-partial-results.md), 3.1) iterates residue classes mod `2^k`: at depth `k`, the numbers with no descent form an explicitly computable union of classes with total density tending to 0. The attempted proof concludes that eventually every class is eliminated, hence all `n` descend.
|
||||
- **Where it breaks.** Density zero does **not** mean empty. At every finite depth the exceptional set is nonempty (infinitely many classes survive), and nothing in the argument prevents a counterexample from living there forever. The implicit step "exceptional density → 0, therefore exceptional set empty" is the error.
|
||||
- **Why it is substantial.** This is not a fringe mistake: the same engine proves the genuine theorems of Terras, Allouche, and Korec. The failure is precisely the gap between "almost all" and "all" ([07](07-open-problems.md), 7.2), and it is the single most common pattern among claimed proofs ([Lagarias bibliography 2003](08-references.md#lagarias-bibliography-2003)).
|
||||
|
||||
## 9.2 The 2-adic conjugacy route (stalled)
|
||||
|
||||
- **Approach.** The parity-vector map conjugates the shortcut map to the shift on `ℤ₂` ([02](02-mathematical-foundations.md), 2.2) — a complete dynamical description. Bernstein made this **non-iterative**: associated to 3x+1 is a permutation `Φ` of the 2-adic integers, and the conjecture is equivalent to the clean statement *"3β is an integer whenever `Φ(β)` is a positive integer"* ([Bernstein 1994](08-references.md#bernstein-1994)). The hope was to prove such analytic statements about `Φ` directly, without iterating trajectories.
|
||||
- **Where it stalls.** The positive integers are a countable, Haar-measure-zero subset of `ℤ₂`. Ergodicity, shift dynamics, and dense periodicity are silent about the countable set the conjecture lives on. Bernstein's elegant equivalent has so far admitted no 2-adic-analytic proof.
|
||||
|
||||
## 9.3 The transfer-operator spectral route (stalled)
|
||||
|
||||
- **Approach.** Via the Berg–Meinardus functional equation ([02](02-mathematical-foundations.md), 2.2), the conjecture becomes a spectral statement about the associated Ruelle–Perron–Frobenius transfer operator: prove that the spectrum contains no eigenvalue beyond those forced by the trivial cycle.
|
||||
- **Where it stalls.** The operator acts on an infinite-dimensional function space whose spectral theory exceeds current analytic tools. Numerical studies confirm the expected spectral picture, but numerics are not proof. Decades after the reformulation, no analytic spectral gap has been established — see also the related analytic extensions in [06](06-generalizations.md), 6.4.
|
||||
|
||||
## 9.4 From "almost all" to "all" (stalled)
|
||||
|
||||
- **Approach.** Push the density program to completion: Terras → Korec → … → full proof. Tao's theorem is the current endpoint ([03](03-partial-results.md), 3.2).
|
||||
- **Where it stalls.** Tao's paper itself identifies the barrier: logarithmic density has only *approximate*, not exact, invariance under the Collatz map, so the "almost bounded minima" argument cannot be iterated down to all `n`. Even the optimistic reading — combining a sufficiently explicit version of the argument with numerical verification — would at best certify a set of **positive logarithmic density** ([Tao 2022](08-references.md#tao-2022)), far short of all integers.
|
||||
|
||||
## 9.5 Baker bounds beyond cycles (stalled)
|
||||
|
||||
- **Approach.** Baker's theory of linear forms in logarithms is the tool behind all cycle-exclusion results ([03](03-partial-results.md), 3.3). Extensions attempt to feed *general* trajectories into the same framework.
|
||||
- **Where it stalls.** Baker bounds need the exact multiplicative structure of a closed cycle (the exponent counts of 2 and 3). Divergent or merely long trajectories have no such closed form to feed in. The bounds also weaken exponentially with the number of odd steps — which is why the cycle frontier creeps forward (`m ≤ 91`) and why the method structurally cannot reach the main conjecture.
|
||||
|
||||
## 9.6 Misapplied deep theorems: Mihăilescu (Catalan) and relatives (failed pattern)
|
||||
|
||||
- **Pattern.** Cycle equations have the form `2^A − 3^m·n = c`. Attempted proofs repeatedly invoke Mihăilescu's theorem (Catalan's conjecture: 8 and 9 are the only consecutive perfect powers) to force a contradiction.
|
||||
- **Why it fails.** Mihăilescu's theorem applies to `c = ±1`; here `c` varies with the cycle structure and is never `±1` outside trivial cases. Importing a deep theorem while silently violating its hypotheses is a documented recurring error ([Lagarias bibliography 2006](08-references.md#lagarias-bibliography-2006)).
|
||||
|
||||
## 9.7 Case study: Opfer 2011 (failed)
|
||||
|
||||
- **The attempt.** Gerhard Opfer (numerical mathematics, Universität Hamburg), *An analytic approach to the Collatz 3n+1 problem*, Hamburger Beiträge zur Angewandten Mathematik, preprint 2011-09 (May 2011) ([Opfer 2011](08-references.md#opfer-2011)). Trajectories are encoded in a tree of "levels"; the proof hinged on the claim that a certain vertex set "will contain all even numbers `2n ≥ 6` exactly once", combined with a cycle analysis.
|
||||
- **The refutation.** The covering claim was incomplete. Opfer attached an author's note declaring the proof claim unfounded; an independent technical critique documenting the failure was published by de Weger ([de Weger 2011](08-references.md#de-weger-2011)).
|
||||
- **Why it is included.** A serious numerical analyst with genuine machinery, refuted within weeks by identifiable technical errors — the archetypal *professional* failed attempt, and a model of community self-correction (in contrast to unaccepted claims that persist unrefuted for years, [07](07-open-problems.md), 7.3).
|
||||
|
||||
## 9.8 The logic route: decidability and independence (stalled)
|
||||
|
||||
- **Approach.** Motivated by Conway's undecidability theorem and the Π⁰₂-completeness of the natural generalization ([06](06-generalizations.md), 6.3), researchers have speculated that the single map `3x+1` might be independent of Peano arithmetic — or at least unreachable by PA-level techniques.
|
||||
- **Where it stalls.** No result exists in either direction: it is unknown whether the Collatz conjecture is provable in PA (or ZFC), and unknown whether it is independent. Unlike, e.g., Goodstein's theorem, there is not even a conditional independence result for this single statement. The route is stalled rather than failed — but nothing actionable has come from it.
|
||||
|
||||
## 9.9 A related stalled attack: Mahler's Z-numbers
|
||||
|
||||
- **The connection.** Descent analyses of the odd step are governed by powers of 3/2. Mahler's 1968 problem asks whether the fractional part of `(3/2)^n` always stays below 1/2 ([Mahler 1968](08-references.md#mahler-1968)) — still open, with partial results by [Flatto, Lagarias, Pollington 1995](08-references.md#flatto-lagarias-pollington-1995).
|
||||
- **Why it matters here.** "Closed-form" approaches that need exact control of the `(3/2)^n` distribution inherit this open problem at their foundation. As long as Z-numbers resist, whole families of descent arguments are blocked.
|
||||
|
||||
## 9.10 Summary: where each route breaks
|
||||
|
||||
| Route | Representative | Break/stall point |
|
||||
|-------|----------------|-------------------|
|
||||
| Modular induction | Terras-style depth iteration | density 0 ≠ empty (9.1) |
|
||||
| 2-adic conjugacy | Bernstein 1994 | `ℕ⁺` measure-zero in `ℤ₂` (9.2) |
|
||||
| Spectral / transfer operator | Berg–Meinardus 1994 | spectrum out of analytic reach (9.3) |
|
||||
| Density program | Tao 2022 endpoint | no invariance of log density (9.4) |
|
||||
| Baker theory | Steiner → Hercher chain | needs closed cycle structure (9.5) |
|
||||
| Deep-theorem import | Mihăilescu in cycle equations | hypotheses not met (9.6) |
|
||||
| Analytic tree encoding | Opfer 2011 | refuted covering lemma (9.7) |
|
||||
| Logic | independence speculation | no results either direction (9.8) |
|
||||
| Z-numbers | Mahler 1968 | independently open (9.9) |
|
||||
|
||||
**Two structural lessons.** (i) *Measure/cardinality gaps*: every statistical or ergodic argument excludes counterexamples only up to a measure-zero set — and the conjecture is about the individual points of that set. (ii) *Hypothesis mismatches*: powerful theorems (Baker, Mihăilescu) enter attempted proofs with their hypotheses quietly violated. Both recur across decades ([Lagarias bibliography 2003](08-references.md#lagarias-bibliography-2003), [Lagarias bibliography 2006](08-references.md#lagarias-bibliography-2006)); the 2026 formal-methods incident ([07](07-open-problems.md), 7.3) added a modern variant — even machine-checked artifacts need verified foundations.
|
||||
@@ -0,0 +1,32 @@
|
||||
# Collatz Problem — Research Documentation
|
||||
|
||||
Research documentation of the **Collatz conjecture** (the `3x+1` problem): the map halves even numbers and sends odd numbers `n` to `3n+1`; the conjecture says every positive integer eventually falls into the cycle `1 → 4 → 2`. It has been open since 1937.
|
||||
|
||||
**Status (August 2026):** unproven; convergence verified for all `n ≤ 2^71`; strongest result: almost all orbits attain almost bounded values (Tao); the problem's generalizations are provably undecidable.
|
||||
|
||||
## Contents
|
||||
|
||||
| # | File | What it covers |
|
||||
|---|------|----------------|
|
||||
| 1 | [01-introduction.md](01-introduction.md) | The problem, the trivial cycle, worked example, history, names, significance |
|
||||
| 2 | [02-mathematical-foundations.md](02-mathematical-foundations.md) | Formal definitions (stopping times), Syracuse map, odd-only map, 2-adic extension, inverse tree, transfer operators |
|
||||
| 3 | [03-partial-results.md](03-partial-results.md) | Rigorous theorems: density results, Tao 2022, cycle nonexistence (Steiner → Hercher) |
|
||||
| 4 | [04-computational-verification.md](04-computational-verification.md) | What verification means, the Barina project (`2^68` → `2^71`), methods, limits, records |
|
||||
| 5 | [05-heuristics.md](05-heuristics.md) | Random-parity model, drift and `6.95 ln n` heuristic, record predictions, what heuristics cannot prove |
|
||||
| 6 | [06-generalizations.md](06-generalizations.md) | Integers and negative cycles, `kx+1` family, generalized maps, Conway/Kurtz–Simon undecidability, p-adic extensions |
|
||||
| 7 | [07-open-problems.md](07-open-problems.md) | The three open questions, why it is hard, status 2026 incl. the Lean kernel incident, prizes |
|
||||
| 8 | [08-references.md](08-references.md) | Central bibliography — all sources and URLs |
|
||||
| 9 | [09-failed-attempts.md](09-failed-attempts.md) | Substantial but failed or stalled proof attempts, refutations, recurring failure patterns |
|
||||
|
||||
## Reading paths
|
||||
|
||||
- **Quick overview:** 1 → 7 (about the status and open problems)
|
||||
- **Rigorous mathematics:** 2 → 3 → 7
|
||||
- **Computation and modeling:** 4 → 5
|
||||
- **History of attempts:** 9 (best after 3)
|
||||
- **Context and related problems:** 6 (at any point)
|
||||
|
||||
## Conventions
|
||||
|
||||
- Each topic lives in exactly one file; cross-references are relative links, citations are author-year anchors into [08-references.md](08-references.md).
|
||||
- Heuristic claims are explicitly labeled as such ([05](05-heuristics.md)); unaccepted claimed proofs are labeled in [07](07-open-problems.md) and [08-references.md](08-references.md).
|
||||
@@ -0,0 +1,48 @@
|
||||
# Forschungsbasis — `docs/` (Faktenkanon)
|
||||
|
||||
> Flughöhe: L2 · Domain: 00-projekt · Stand: 2026-08-29
|
||||
|
||||
## In 3 Sätzen
|
||||
|
||||
Die englische Recherche-Doku unter `docs/` ist der **Faktenkanon**: jedes mathematische Faktum im Manuskript ist hier verbürgt — mit Quelle, URLs zentral nur in `08-references.md`. Das Manuskript (deutsch) leitet sich daraus ab, fügt aber keine Fakten hinzu. Korrektur-Loop: erst `docs/` (mit Quelle), dann Manuskript.
|
||||
|
||||
## Wann laden
|
||||
|
||||
- Kapitel schreiben/reviewen und ein Faktum braucht Beleg
|
||||
- Unklarheit „wie genau war der Stand?“
|
||||
- Neu recherchierte Fakten einarbeiten (dort, nicht im Manuskript)
|
||||
|
||||
## Fakten / Regeln (kurz)
|
||||
|
||||
| Datei | Thema | Typische Kapitel-Nutzung |
|
||||
|-------|-------|--------------------------|
|
||||
| `docs/index.md` | Navigation (nur Links) | Einstieg |
|
||||
| `docs/01-introduction.md` | Problem, Geschichte, Warum-so-schwer | Einstiegs- und Historienmaterial |
|
||||
| `docs/02-mathematical-foundations.md` | Formalisierung, Shortcut-Map, 2-adisch, Transferoperatoren | Kapitel „Die Maschinerie“ |
|
||||
| `docs/03-partial-results.md` | Terras/Korec-Dichten, Tao „fast alle“, Zyklen (Steiner → Simons/de Weger → Hercher) | Kapitel „Was bewiesen ist“ |
|
||||
| `docs/04-computational-verification.md` | Barina-Verifikation `2^68 → 2^71`, Rekorde, Human-LLM-Studie | Kapitel „Rechen-/Rekordwelt“ |
|
||||
| `docs/05-heuristics.md` | Stochastisches Modell, Drift, Rekordvorhersagen, Grenzen der Heuristik | Kapitel „Warum man trotzdem rechnet“ |
|
||||
| `docs/06-generalizations.md` | Negative Zahlen, kx+1, generalisierte Maps, Conway/Kurtz–Simon, p-adisch | Kapitel „Die Familie um das Problem“ |
|
||||
| `docs/07-open-problems.md` | Offene Fragen, Härte, Status 2026 inkl. Lean-Kernel-Vorfall, Preise | Kapitel „Offen“ |
|
||||
| `docs/08-references.md` | Zentrale Bibliographie — **alle URLs** | Quellenziel für Autor+Jahr-Zitate |
|
||||
| `docs/09-failed-attempts.md` | Gescheiterte/gestrandete substanzielle Beweisversuche (Fallstudie Opfer 2011 u. a.) | Kapitel „Die Beweisversuche“ |
|
||||
|
||||
**Englisch vs. Deutsch:** `docs/` bleibt englisch; Manuskript-Kapitel sind deutsch. Übersetzung ist Abgabe des Schreib-Tasks, nicht Datei-Umbenennung.
|
||||
|
||||
**Faktenschutz:** Formulierungen (Grenzen, Rekorde, „fast alle“) unverändert aus `docs/` übernehmen; keine Verschärfung/Abschwächung. Details: `AGENTS.md` § Faktenschutz.
|
||||
|
||||
## Source of Truth (L3)
|
||||
|
||||
| Thema | Pfad |
|
||||
|-------|------|
|
||||
| Fakten selbst | `docs/0*.md` (je nach Thema, siehe Tabelle) |
|
||||
| URLs | `docs/08-references.md` (ausschließlich) |
|
||||
|
||||
## Nicht hier
|
||||
|
||||
- Terminologie-Übersetzungen → `.commandcode/rules/schreibkonventionen.md` § Terminologie
|
||||
- Kapitelgliederung → `00-inhaltsverzeichnis.md` (sobald vorhanden)
|
||||
|
||||
## Freshness
|
||||
|
||||
- Neue Recherche: `docs/` ergänzen (mit Quelle + Datum), dann Datei-Tabelle hier knapp aktualisieren.
|
||||
@@ -0,0 +1,43 @@
|
||||
# Projekt-Überblick
|
||||
|
||||
> Flughöhe: L2 · Domain: 00-projekt · Stand: 2026-08-29
|
||||
|
||||
## In 3 Sätzen
|
||||
|
||||
Laien-Sachbuch *Die Collatz-Vermutung* (Arbeitstitel) — die offene Frage über die 3n+1-Iteration, erzählt für neugierige Erwachsene ohne mathematische Vorbildung. Nüchtern und ehrlich: ungelöst bleibt ungelöst. Dieses Repo steuert **Autoren-Agents**; die Faktenbasis ist die englische Recherche-Doku unter `docs/`.
|
||||
|
||||
## Wann laden
|
||||
|
||||
- Neuer Agent ohne Repo-Bild
|
||||
- Unklarheit Autoren-Harness vs. Forschungsbasis vs. Manuskript
|
||||
|
||||
## Fakten / Regeln (kurz)
|
||||
|
||||
Titel, Publikum, Ton, Faktenschutz: **[`AGENTS.md`](../../../AGENTS.md)** (immer geladen). Pfad-Rollen: [repo-karte.md](repo-karte.md) / [source-of-truth.md](source-of-truth.md) — hier nicht wiederholen.
|
||||
|
||||
| Ort | Rolle |
|
||||
|-----|-------|
|
||||
| `AGENTS.md`, `.commandcode/`, `docs/kb/` | steuert Agents **am Buch** |
|
||||
| `docs/0*.md` | Forschungsbasis (englisch) — Faktenkanon |
|
||||
| `NN-*.md` (Root) | Manuskript / PDF |
|
||||
| `HANDOFF-collatz.md` | aktueller Slice |
|
||||
| `kladde.md` | privat |
|
||||
|
||||
**Schwesterprojekt:** `../books/ki-coding-agents-praxis` (Fachbuch „Coding Agents in der Praxis") — Quelle der übernommenen Infrastruktur (Skills, Pipeline, KB-Muster). Nur lesen, nie verändern; inhaltlich unabhängig.
|
||||
|
||||
## Source of Truth (L3)
|
||||
|
||||
| Thema | Pfad |
|
||||
|-------|------|
|
||||
| Projektregeln | [`AGENTS.md`](../../../AGENTS.md) |
|
||||
| Projektüberblick | [`README.md`](../../../README.md) |
|
||||
| Session | [`HANDOFF-collatz.md`](../../../HANDOFF-collatz.md) |
|
||||
|
||||
## Nicht hier
|
||||
|
||||
- Faktensuche → [forschungsbasis.md](forschungsbasis.md)
|
||||
- Schreib-/Build-Details → Domain 01 / Skill `pdf-bauen`
|
||||
|
||||
## Freshness
|
||||
|
||||
- Titel/Regeln nur bei Meta-Change (dann AGENTS.md, nicht diese Karte aufblasen).
|
||||
@@ -0,0 +1,38 @@
|
||||
# Repo-Karte
|
||||
|
||||
> Flughöhe: L2 · Domain: 00-projekt · Stand: 2026-08-29
|
||||
|
||||
## In 3 Sätzen
|
||||
|
||||
Welches Verzeichnis wofür — damit Agents nicht in `docs/` Kapiteltexte ablegen oder Fakten ins Manuskript erfinden. Die Edit-Tabelle steht in [source-of-truth.md](source-of-truth.md); hier der Verzeichnis-Blick.
|
||||
|
||||
## Wann laden
|
||||
|
||||
- Unklarheit „wohin mit dieser Datei?“
|
||||
- Neuer Agent ohne Repo-Bild
|
||||
|
||||
## Fakten / Regeln (kurz)
|
||||
|
||||
| Pfad | Rolle | Nicht |
|
||||
|------|-------|-------|
|
||||
| `00-inhaltsverzeichnis.md` | Navigation, nicht im PDF | als Kapitel behandeln |
|
||||
| `NN-*.md` (Root) | Kapitel (PDF-Inhalt) — noch keine vorhanden | in KB dumpen |
|
||||
| `docs/` (0*.md) | **Forschungsbasis** (englisch, Faktenkanon) | als Manuskript behandeln; ohne Auftrag ändern |
|
||||
| `docs/kb/` | Autoren-KB (erste Informationsquelle) | Kapitel-Volltext |
|
||||
| `AGENTS.md`, `.commandcode/` | Autoren-Harness am Buch | Leser-Content |
|
||||
| `HANDOFF-collatz.md` | aktueller Slice | Chronik |
|
||||
| `pdf/`, `scripts/`, `justfile` | PDF-Pipeline | ohne Auftrag anfassen |
|
||||
| `reviews/` | Prüfprotokolle | als SoT für Content |
|
||||
| `kladde.md` | privat | ohne Auftrag |
|
||||
| `build/`, `dist/` | generiert | handpatchen |
|
||||
| `assets/` | Figuren/Cover (später) | Roh-Drops nach `pics/` (gitignored) |
|
||||
|
||||
## Source of Truth (L3)
|
||||
|
||||
| Thema | Pfad |
|
||||
|-------|------|
|
||||
| SoT-Tabelle | [source-of-truth.md](source-of-truth.md) |
|
||||
|
||||
## Freshness
|
||||
|
||||
- Neues Top-Level-Verzeichnis: diese Karte + [source-of-truth.md](source-of-truth.md) in derselben Session.
|
||||
@@ -0,0 +1,40 @@
|
||||
# Source of Truth
|
||||
|
||||
> Flughöhe: L2 · Domain: 00-projekt · Stand: 2026-08-29
|
||||
|
||||
## In 3 Sätzen
|
||||
|
||||
Welche Datei darf wer ändern — und wo ist was verbindlich. Gegenstück zur Verzeichnis-Sicht [repo-karte.md](repo-karte.md).
|
||||
|
||||
## Wann laden
|
||||
|
||||
- Vor jedem Write/Edit: „darf ich das?“
|
||||
- Unklarheit, wo eine Änderung hingehört
|
||||
|
||||
## Edit-Tabelle
|
||||
|
||||
| Datei/Ort | Wer (welcher Task) | Änderung ohne Auftrag |
|
||||
|-----------|--------------------|------------------------|
|
||||
| `NN-*.md` (Manuskript) | Schreib-/Lektorat-Tasks | ja, im Task-Scope |
|
||||
| `00-inhaltsverzeichnis.md` | Struktur-Tasks; danach verbindlich | nein — Struktur-Labels gelten |
|
||||
| `docs/0*.md` (Forschungsbasis) | nur Fakten-Recherche-Tasks, **mit Quelle** | **nein** |
|
||||
| `docs/kb/**` | KB-Pflege bei Domänen-Änderung | ja, schlank halten |
|
||||
| `AGENTS.md` | nur Meta-Change (Regeln/Ton/Workflow) | nein |
|
||||
| `.commandcode/rules/schreibkonventionen.md` | nur Meta-Change (Ton/Terminologie) | nein |
|
||||
| `.commandcode/skills/**`, `commands/**` | Harness-Pflege | nein |
|
||||
| `justfile`, `scripts/`, `pdf/` | nur Pipeline-Tasks | **nein** |
|
||||
| `kladde.md` | nur Autor | **nein** |
|
||||
| `HANDOFF-collatz.md` | jede Session (Meta/Slice/Offen) | ja — Datei ist Handoff |
|
||||
| `reviews/` | nach total-check | ja (neues Protokoll) |
|
||||
| `README.md` | bei Struktur-/Ziel-Änderung | ja, knapp |
|
||||
| `build/`, `dist/` | Pipeline | generiert |
|
||||
|
||||
## Stille Regeln
|
||||
|
||||
- Faktenschutz-Wortlaut (`AGENTS.md`) nicht ohne expliziten Meta-Auftrag ändern.
|
||||
- Neue Top-Level-Datei → repo-karte + source-of-truth in derselben Session mitziehen.
|
||||
- URL-Ziele landen nur in `docs/08-references.md`; Manuskript zitiert Autor+Jahr.
|
||||
|
||||
## Freshness
|
||||
|
||||
- Bei neuen Platzhaltern (assets/, prompts/): Tabelle erweitern, nicht neu erfinden.
|
||||
@@ -0,0 +1,47 @@
|
||||
# Stil und Ton
|
||||
|
||||
> Flughöhe: L2 · Domain: 01-manuskript · Stand: 2026-08-29
|
||||
|
||||
## In 3 Sätzen
|
||||
|
||||
Stimme eines verlässlichen Erklärers: präzise, geduldig, ehrlich — neugierig statt sensationslüstern. Ungelöst bleibt ungelöst; Heuristik heißt Heuristik. Beispiele vor Formeln, Fachbegriffe beim Erstauftreten erklärt.
|
||||
|
||||
## Wann laden
|
||||
|
||||
- Prosa-Edits, Lektorat, Humanizer-Vorarbeit
|
||||
- Unsicherheit „klingt das nach dem Buch?“
|
||||
|
||||
## Fakten / Regeln (kurz)
|
||||
|
||||
**Haltung**
|
||||
|
||||
- Laien-Publikum ohne Vorbildung; jede Fachformel umgangssprachlich aufgelöst.
|
||||
- Analogien nur als markierte Vergleichshilfe („Bild, kein Beweis“).
|
||||
- Kein Hype, keine Mystifikation, keine „gelöst!“-Framings.
|
||||
- Deutsch durchgängig; Namen/Fachbegriffe original mit Übersetzung bei Erstnennung.
|
||||
|
||||
**Vermeiden**
|
||||
|
||||
- Floskeln ohne Erkenntnisfolge
|
||||
- Ungefragte Exkurse, „interessante Fakten“, Genie-Kitsch
|
||||
- Zahlen ohne Kontext
|
||||
- Gesamtrewrite „aus Prinzip“
|
||||
|
||||
## Source of Truth (L3)
|
||||
|
||||
| Thema | Pfad |
|
||||
|-------|------|
|
||||
| Vollständige Schreibregeln | `.commandcode/rules/schreibkonventionen.md` |
|
||||
| Wärme-Bausteine | `.commandcode/skills/lektorat/references/waerme.md` |
|
||||
| Kurz-Rules | [`AGENTS.md`](../../../AGENTS.md) § 1–4 |
|
||||
| Procedural Lektorat | `.commandcode/skills/lektorat/SKILL.md` |
|
||||
| Procedural Humanizer | `.commandcode/skills/humanizer/SKILL.md` |
|
||||
|
||||
## Nicht hier
|
||||
|
||||
- Fachterminologie-Kanon → [terminologie.md](terminologie.md)
|
||||
- Faktenschutz → `AGENTS.md` § Faktenschutz
|
||||
|
||||
## Freshness
|
||||
|
||||
- Stil-Kanon ändert sich selten; bei Humanizer-Marker-Katalog: Skill-References.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Terminologie (kanonisch)
|
||||
|
||||
> Flughöhe: L2 · Domain: 01-manuskript · Stand: 2026-08-29
|
||||
|
||||
## In 3 Sätzen
|
||||
|
||||
Einheitliche Fachbegriffe im Manuskript und in Autoren-Artefakten. Verwechslungen (Stoppzeit vs. Gesamtstoppzeit, log-Dichte vs. natürliche Dichte, Shortcut-Map vs. klassische Map) sind typische Review-Funde. Bei neuen Begriffen: zuerst Schreibkonventionen, dann Kapitel-Erstauftreten.
|
||||
|
||||
## Wann laden
|
||||
|
||||
- Fachbegriff einführen oder umformulieren
|
||||
- Lektorat/Review auf Konsistenz
|
||||
|
||||
## Fakten / Regeln (kurz)
|
||||
|
||||
**Kanon-Tabelle:** `.commandcode/rules/schreibkonventionen.md` § Terminologie (L3, always geladen). Hier nur die häufigsten Fallen:
|
||||
|
||||
| Falle | Richtig |
|
||||
|-------|---------|
|
||||
| „Stoppzeit“ für Schritte bis 1 | Gesamtstoppzeit; Stoppzeit = erstmalig unter Startzahl (Terras) |
|
||||
| „fast alle“ als „alle“ | fast alle = log-Dichte 1; nie strecken |
|
||||
| „die Rechnung hat es bewiesen“ | Verifikationsgrenze 2^71 = Beobachtung, kein Beweis |
|
||||
| „2-adisch“ = „binär“ | 2-adische Zahlen `ℤ₂` sind ein eigenes Objekt; beim Erstauftreten trennen |
|
||||
| „Conway bewies: Collatz ist unentscheidbar“ | Undecidability gilt für **Generalisierungen** (Conway 1972; Kurtz–Simon 2007) |
|
||||
| „Zyklus“ im Alltagssinn | m-Zyklus: geschlossener Orbit mit m ungeraden Schritten |
|
||||
| Shortcut-Map vs. Original | `T(n)=(3n+1)/2` (shortcut) vs. `C(n)=3n+1`; einmal benennen, dann konsistent |
|
||||
|
||||
## Source of Truth (L3)
|
||||
|
||||
| Thema | Pfad |
|
||||
|-------|------|
|
||||
| Vollständige Tabelle | `.commandcode/rules/schreibkonventionen.md` § Terminologie |
|
||||
|
||||
## Freshness
|
||||
|
||||
- Neue Begriffe: Erstauftreten im Manuskript definieren, dann hier + Schreibkonventionen nachziehen.
|
||||
@@ -0,0 +1,175 @@
|
||||
# Video-Inhaltskarte „Die Collatz-Vermutung“ — populäre Erklärvideos
|
||||
|
||||
> Autoren-KB · Quellenmaterial, **nicht im PDF** · Ur-Fassung geprüft gegen die Forschungsbasis (`docs/`) + Web-Recherche · Stand: 2026-08-29
|
||||
> Status der Video-Inhalte: populärwissenschaftliche Erklärungen, **kein Beweis** („ungelöst bleibt ungelöst“).
|
||||
> Wiederkehrendes Narrativ: Regel trivial, Beweis fehlt; Rechen-Check bis ~`2^68` (Produktionsstand 2021 — heute `2^71`, siehe Abschnitt 6); stärkstes analytisches Resultat Tao (Preprint 2019, publiziert 2022, „almost all“).
|
||||
> Prüfprotokoll mit Kanon-Ankern und Korrektur-Log: Abschnitt 7.
|
||||
|
||||
---
|
||||
|
||||
## 1. Kanonische Regel (alle Videos)
|
||||
|
||||
- `n` gerade → `n/2`; `n` ungerade → `3n+1`
|
||||
- Vermutung: jede positive ganze Zahl landet bei 1 und damit im Zyklus **1 → 4 → 2 → 1** (Kanon-Formulierung, `docs/01` §1.1).
|
||||
- Aliase in Videos: 3n+1 / 3x+1, Hasse-Algorithmus, Ulam, Kakutani, Syracuse, Thwaites, Hailstone-Zahlen — vollständige kanonische Liste: [`docs/01-introduction.md`](../../01-introduction.md) §1.4.
|
||||
- Ursprung: Lothar Collatz, Hamburg 1937 — nach eigener späterer Erinnerung, damals unveröffentlicht („Since I could not solve the [3n+1] problem, I did not publish the conjecture“); Verbreitung in den 1950ern über Hasse und Kakutani — [`docs/01`](../../01-introduction.md) §1.3. Videos nennen pauschal „1937“.
|
||||
|
||||
---
|
||||
|
||||
## 2. Kernvideos (Inhalt + genannte Quellen)
|
||||
|
||||
### A. Veritasium — *The Simplest Math Problem No One Can Solve*
|
||||
- URL: <https://www.youtube.com/watch?v=094y1Z2wpJg>
|
||||
- 2021, ~22 min; Aufrufzahl der Ur-Fassung „~46 Mio“ — YouTube-Abfrage (29.08.2026) liefert keinen Zähler, **Zahl ungeprüft**. Referenzvideo, das fast alle späteren Videos zitieren.
|
||||
- Inhalt (kompakt, geprüft):
|
||||
- Beispiele 7 und 27; 27: 111 Schritte, Peak 9232 — kanonisch `docs/01` §1.2, `docs/04` §4.4.
|
||||
- Hailstone-Sequenzen, Stopping Time, gerichteter Graph / „Korallen“-Visualisierung inverser Trajektorien.
|
||||
- Heuristik: Shortcut-Schritt ×3/2 (ungerade) bzw. ×1/2 (gerade); E[Δ log n] = ½·log(3/4); typischer Faktor ≈ 0,866 pro Schritt; τ(n) ≈ 6,95·ln n — Kanon-Formulierung [`docs/05-heuristics.md`](../../05-heuristics.md) §5.1. Der in Videos genannte „≈3/4-Faktor“ ist die Drift-Formulierung davon.
|
||||
- Benfordsches Gesetz — **Video-Aussage** (Kontorovich–Miller), nicht im Kanon.
|
||||
- Zwei Falsifikationswege: divergente Bahn **oder** anderer Zyklus.
|
||||
- Negative Zahlen: weitere Zyklen — präzise: drei bekannte ({−1, −2}, {−5, −14, −7, −20, −10}, 18-elementig ab −17); äquivalent zum 3x−1-Problem — [`docs/06-generalizations.md`](../../06-generalizations.md) §6.1.
|
||||
- Rechnerisch: „keine Gegenbeispiele bis `2^68`“ — zum Produktionszeitpunkt (2021) korrekt (Barina 2020); aktuell `2^71`, siehe Abschnitt 6.
|
||||
- „Almost all“-Resultate: Terras 1976 (fast alle fallen unter den Startwert; Everett 1977 unabhängig) — `docs/03` §3.1; **Tao**: Preprint 2019 (arXiv:1909.03562), publiziert 2022, *Forum of Mathematics, Pi* 10, e12 — `docs/03` §3.2.
|
||||
- Undecidability: Conway 1972 (generalized Collatz, Totalität unentscheidbar) + FRACTRAN 1987; ergänzend Kurtz–Simon 2007 (Π⁰₂-complete); entscheidende Nuance: gilt für **Familien** von Maps, nicht für `3n+1` selbst — [`docs/06`](../../06-generalizations.md) §6.3.
|
||||
- Pólya-Gegenbeispiel als Warnung: Haselgrove (1958) widerlegte die Vermutung; die **1,845·10^361 ist seine Nicht-Konstruktions-Schätzung der Grenze**, nicht das Gegenbeispiel — explizit: Lehman 1960 (906.180.359), kleinstes bekanntes: Tanaka 1980 (906.150.257). Quelle: Wikipedia „Pólya conjecture“ (Recherche 29.08.2026; kein Kanon-Eintrag).
|
||||
- Genannte Quellen im Video/Description:
|
||||
- Lagarias 2003, 2006 (annotated bibliographies) — im Kanon `docs/08`; Lagarias 2010 (*The Ultimate Challenge*) — im Kanon `docs/08`.
|
||||
- Tao 2019 (arXiv:1909.03562); Tao-Talk „The Notorious Collatz Conjecture“.
|
||||
- Kontorovich–Sinai 2002, Kontorovich–Miller (Benford), Kontorovich–Lagarias 2010 — **Video-Angaben**, im Kanon nur der Sammelband.
|
||||
- Conway 1987 FRACTRAN — im Kanon `docs/08`.
|
||||
- Interview/Beratung: Alex Kontorovich. Erdős-Zitat „Mathematics may not be ready for such problems“ — im Kanon `docs/01` §1.3.
|
||||
- Credits: Derek Muller, Alex Kontorovich, Petr Lebedev.
|
||||
|
||||
### B. Numberphile — *UNCRACKABLE? The Collatz Conjecture* (David Eisenbud)
|
||||
- URL: <https://www.youtube.com/watch?v=5mFpVDpKX70> · Extra: <https://www.youtube.com/watch?v=O2_h3z1YgEU>
|
||||
- Inhalt: Regel + Baum-Visualisierung, Hailstones, OEIS-Rekordtabellen, Check „~`2^60`“ (**Video-Angabe, damaliger Stand**), Erdős/Lagarias-Warnung, Variante 3n−1 (äquivalent zum Negativ-Strang, `docs/06` §6.1).
|
||||
- Quellen im Video: Wikipedia-Bäume, OEIS, Lagarias, Erdős.
|
||||
|
||||
### C. Numberphile — *Collatz Conjecture in Color* (Alex Bellos / Edmund Harriss)
|
||||
- URL: <https://www.youtube.com/watch?v=LqKpkdRRLZw>
|
||||
- Inhalt: Färbung/Visualisierung der Iterationen; Buch *Visions of Numberland*. Wenig Theorie, viel Bild.
|
||||
|
||||
### D. NJ Wildberger — *The Collatz conjecture (3n+1 problem)*
|
||||
- URL: <https://www.youtube.com/watch?v=K0yMyUn--0s> (~33 min)
|
||||
- Inhalt: Geschichte 1937, Evidenz, Varianten (u. a. 5n+1 / Roosendaal), Strategie **Basis 2 / 3 / 6** (**Video-Ansatz**), Übungen.
|
||||
- 5n+1 kanonisch: zwei bekannte nichttriviale Zyklen und Bahnen mit mutmaßlicher Divergenz — beide Versagensmodi real — [`docs/06`](../../06-generalizations.md) §6.2. Roosendaal-Datenbank: `docs/04` §4.4.
|
||||
- Genannt: Lagarias-Survey, Oliveira e Silva, Roosendaal, Hailstone/Syracuse/Kakutani/Ulam.
|
||||
|
||||
### E. Michael Penn — *Collatz Conjecture – The Interns' Inception*
|
||||
- URL: <https://www.youtube.com/watch?v=JXPmqL69ZHo>
|
||||
- Inhalt: Shortcut-Map `T(n) = n/2` bzw. `(3n+1)/2` (kanonisch `docs/05` §5.1); heuristischer Erwartungswert; Zyklen; Gaußsche Zahlen als Abstecher (**Video-Exkurs**).
|
||||
- Quelle: Lagarias *The 3x+1 problem and generalizations* (= Lagarias 1985, im Kanon `docs/08`).
|
||||
|
||||
### F. Highly Entropic Mind — *My honest attempt … #SoME3*
|
||||
- URL: <https://www.youtube.com/watch?v=8iJOTKMg5-k>
|
||||
- Inhalt: Collatz-Baum aus 3 Kacheln; Konstellationen; Chaos; negative Zyklen; Verweis auf Veritasium. Kein akzeptierter Beweis.
|
||||
|
||||
### G. Deutschsprachige Videos (gleiche Kernfakten)
|
||||
- Weitz / HAW Hamburg: <https://www.youtube.com/watch?v=k2RRQtkjtCY>
|
||||
Geschichte, Binärsystem, **Terras/Everett** (probabilistisches Verhalten wird *bewiesen*, nicht die Vermutung — korrekt, `docs/03` §3.1), Tao-Verbesserung (publiziert 2022), Entscheidbarkeit, Warnung an Hobby-„Beweise“.
|
||||
- Endlich Verständlich: <https://www.youtube.com/watch?v=G_AnKK9NdXc>
|
||||
Regeln, Gegenbeispielsuche, weitere Zyklen, Fallzeiten, Peaks, Induktion scheitert, Tao-Teillösung.
|
||||
- 3sat NANO / Gert Scobel: <https://www.youtube.com/watch?v=CNsMLqC_mis>
|
||||
Popularisierung + Verweis auf Veritasium; philosophisch (Attraktor, Iteration).
|
||||
- Kürzere DE-Clips (Mathegym, Entwurzler, Weitz 2017): Regel + `2^68`-Check + „kein Beweis“.
|
||||
|
||||
### H. Seit 2023 (Recherche 29.08.2026)
|
||||
- **Keine nennenswerten neuen Mainstream-Collatz-Videos gefunden** (nur Kleinstkanäle).
|
||||
- Kandidat, nicht näher geprüft: *I Wasted One Year of Compute Time on THIS* — <https://www.youtube.com/watch?v=cTgia2QSsec> (Collatz-Visualisierung, referenziert Veritasium).
|
||||
|
||||
---
|
||||
|
||||
## 3. Wiederkehrende Fakten (Video-Konsens, gegen Kanon abgeglichen)
|
||||
|
||||
| Thema | Was Videos sagen | Kanon-Status |
|
||||
|---|---|---|
|
||||
| Check-Grenze | Meist `2^68` (~3·10²⁰); älteres Numberphile „~`2^60`“ | Damals korrekt; **aktueller belegter Rekord `2^71`** (Barina 2025) — `docs/04` §4.2 |
|
||||
| Bekannter Zyklus | Nur 1-4-2 im Positiven; negative Zahlen haben weitere Zyklen | Korrekt; 3 negative Zyklen — `docs/06` §6.1 |
|
||||
| Rekord-Beispiel | 27: langer Anstieg, Peak 9232 | Korrekt — `docs/01` §1.2, `docs/04` §4.4 |
|
||||
| Heuristik | Odd-step ≈ ×3/2; gemittelt Schrumpfen („3/4“) | Kanon-Formulierung — `docs/05` §5.1 |
|
||||
| Teilresultate | Terras 1976; Tao „almost all“ (log. Dichte) | Terras 1976 (+ Everett 1977) `docs/03` §3.1; Tao 2022 (Preprint 2019) `docs/03` §3.2; konkret: Korec 1994 (`n^0,7925`), Krasikov–Lagarias 2003 (`x^0,84`) |
|
||||
| Undecidability | Conway 1972/1987: *Verallgemeinerungen* unentscheidbar | Korrekt, ergänzt Kurtz–Simon 2007 (Π⁰₂-complete); Nuance Familien vs. `3n+1` — `docs/06` §6.3 |
|
||||
| Warnung | Erdős; Lagarias als Autorität; „nicht daran arbeiten“ | Erdős-Zitat `docs/01` §1.3; Lagarias-Surveys `docs/08` |
|
||||
|
||||
---
|
||||
|
||||
## 4. Quellen-Palimpsest (von Videos genannt, mit Kanon-Status)
|
||||
|
||||
1. Lagarias 1985 (Survey), 2003/2006 (Bibliografien), *Ultimate Challenge* 2010 — **im Kanon** `docs/08`
|
||||
2. Tao 2022 (Preprint 2019, arXiv:1909.03562) — **im Kanon** `docs/08`
|
||||
3. Terras 1976 + Everett 1977 — **im Kanon** `docs/08`
|
||||
4. Conway 1972 / 1987; Kurtz–Simon 2007 — **im Kanon** `docs/08`
|
||||
5. Kontorovich + Sinai / Miller / Lagarias (stochastische Modelle, Benford) — **nur Video-Angabe**
|
||||
6. Computational: Oliveira e Silva, Roosendaal, Barina — **im Kanon** `docs/04`, `docs/08`
|
||||
7. OEIS-Rekordtabellen — nur Video; kanonisches Pendant: Roosendaal-Datenbank (`docs/04` §4.4)
|
||||
8. Neu seit den Videos: Hercher 2023 (`m ≤ 91`), Barina 2025 (`2^71`) — Abschnitt 6
|
||||
|
||||
---
|
||||
|
||||
## 5. Was Videos *nicht* liefern
|
||||
|
||||
- Keinen gültigen allgemeinen Beweis.
|
||||
- Keine einheitliche „beste“ Implementierung (Shortcut `(3n+1)/2` vs. klassisch `3n+1`).
|
||||
- Visualisierungen (Koralle, gefärbter Baum, inverse Graphen) sind pädagogisch, nicht beweisführend.
|
||||
- Viele Hobby-„Proof“-Videos existieren — Videos markieren sie meist als unbewiesen/crank-risk. Kanonisch dokumentierte Beispiele der Gattung: Claimed proof 2025 (arXiv:2502.20642, nicht akzeptiert) und der Lean-Kernel-Incident 2026 (KI-generierte „Widerlegung“ scheiterte an zwei Lean-Kernel-Bugs) — `docs/07` §7.3, `docs/04` §4.5, `docs/08`.
|
||||
|
||||
---
|
||||
|
||||
## 6. Neu seit den Videos (Forschungsbasis, Stand 2026-08-29)
|
||||
|
||||
- **Verifikationsgrenze `2^71`** — aktueller Rekord, Barina 2025 (*J Supercomput* 81, 810; verifiziert laut Projekt-Log am 15.01.2025; Projektseite abgerufen 29.08.2026, Arbeit läuft Richtung nächstem Block 2076·2^60). `docs/04` §4.2, `docs/08`.
|
||||
- **Keine nichttrivialen m-Zyklen für `m ≤ 91`** (Hercher 2023, verbesserte Baker-Schranken). Kombiniert mit `2^71`: ein nichttrivialer Zyklus müsste **> 91 lokale Minima** haben und ein **Minimum > `2^71`** — `docs/03` §3.3.
|
||||
- **„Verschärfungen“ konkretisiert:** Korec 1994 (fast alle Bahnen unter `n^0,7925`), Krasikov–Lagarias 2003 (mindestens `x^0,84` Zahlen ≤ x erreichen 1) — `docs/03` §3.1.
|
||||
- **kx+1-Familie:** Drift √k/2; k = 3 ist der einzige nichttriviale Fall mit erwartetem Abwärtsdrift; 5n+1 hat nichttriviale Zyklen **und** mutmaßlich divergente Bahnen — beide Versagensmodi der Vermutung real — `docs/06` §6.2.
|
||||
- **Tao publiziert:** *Forum of Mathematics, Pi* 10 (2022), e12 — Zitation „Tao 2022 (Preprint 2019)“, nicht mehr „Tao 2019“ — `docs/03` §3.2.
|
||||
- **2026-Ereignisse (Kontext für crank-risk-Narrativ):** Lean-Kernel-Incident (25.07.2026, KI-„Widerlegung“ an zwei Kernel-Soundness-Bugs gescheitert, #14576/PR #14577), Claimed proof 2025 (arXiv:2502.20642, nicht akzeptiert), Large-Scale-Studie arXiv 2603.11066 (~10^14 Trajektorien, **Preprint**), Bakuage-Preis (120 Mio. JPY, 2017), Smyth 2026 Community-Literature-Review — `docs/07` §7.3, `docs/04` §4.4–4.5, `docs/08`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Abgleich mit der Forschungsbasis (Prüfprotokoll, 29.08.2026)
|
||||
|
||||
### 7.1 Kanon-Anker
|
||||
|
||||
| Thema | Anker |
|
||||
|---|---|
|
||||
| Regel, Zyklus, Aliase | [`docs/01`](../../01-introduction.md) §1.1, §1.4 |
|
||||
| Ursprung 1937 | [`docs/01`](../../01-introduction.md) §1.3 |
|
||||
| 27: τ=111, M=9232 | [`docs/01`](../../01-introduction.md) §1.2, [`docs/04`](../../04-computational-verification.md) §4.4 |
|
||||
| Terras/Everett, Korec, Krasikov–Lagarias | [`docs/03`](../../03-partial-results.md) §3.1, [`docs/08`](../../08-references.md) |
|
||||
| Tao | [`docs/03`](../../03-partial-results.md) §3.2, [`docs/08`](../../08-references.md) |
|
||||
| Heuristik (3/4-Drift, τ ≈ 6,95·ln n) | [`docs/05`](../../05-heuristics.md) §5.1 |
|
||||
| Zyklen `m ≤ 91` | [`docs/03`](../../03-partial-results.md) §3.3 |
|
||||
| Verifikation `2^68`/`2^71` | [`docs/04`](../../04-computational-verification.md) §4.2, [`docs/08`](../../08-references.md) |
|
||||
| Roosendaal | [`docs/04`](../../04-computational-verification.md) §4.4 |
|
||||
| Negative Zyklen / 3x−1 / 5n+1 | [`docs/06`](../../06-generalizations.md) §6.1–6.2 |
|
||||
| Undecidability (Conway, Kurtz–Simon) | [`docs/06`](../../06-generalizations.md) §6.3, [`docs/08`](../../08-references.md) |
|
||||
| crank-risk / 2026-Incidents | [`docs/07`](../../07-open-problems.md) §7.3, [`docs/08`](../../08-references.md) |
|
||||
|
||||
### 7.2 Video-only (nicht als Fakt verkaufen)
|
||||
|
||||
Benford / Kontorovich–Miller · Kontorovich–Sinai 2002 · Wildberger-Basis-2/3/6-Strategie · Penn-Gaußsche Zahlen · Numberphile „~`2^60`“ (damaliger Stand) · Veritasium-View-Zahl (~46 Mio, ungeprüft)
|
||||
|
||||
### 7.3 Korrekturen gegenüber der Ur-Fassung
|
||||
|
||||
1. **Tao:** „2019“ → „Preprint 2019, publiziert 2022“ (drei Stellen). Anker `docs/03` §3.2, `docs/08`.
|
||||
2. **Pólya:** 1,845·10^361 als Haselgroves Nicht-Konstruktions-Schranke etikettiert; ergänzt Lehman 1960 (906.180.359) und Tanaka 1980 (906.150.257, kleinstes Gegenbeispiel).
|
||||
3. **`2^71`:** von „z. B. (Literatur)“ zu belegtem aktuellen Rekord (Barina 2025; Projektseite 29.08.2026).
|
||||
4. **Zyklus-Richtung:** „4→2→1→4“ → kanonisch „1 → 4 → 2 → 1“.
|
||||
5. **Kurtz–Simon 2007** ergänzt; Nuance „Familien, nicht `3n+1` selbst“.
|
||||
6. **Negative Zyklen** konkretisiert (drei Zyklen, 3x−1-Äquivalenz).
|
||||
7. **Everett 1977** als unabhängiges Terras-Resultat ergänzt (war nur beim Weitz-Video erwähnt).
|
||||
8. **View-Zahl** Veritasium als ungeprüft markiert.
|
||||
9. **Neue Videos seit 2023:** keine nennenswerten Mainstream-Beiträge gefunden; Kandidat cTgia2QSsec vermerkt (Abschnitt 2H).
|
||||
|
||||
---
|
||||
|
||||
## 8. Empfohlene Verarbeitungsreihenfolge für Coding-Agent
|
||||
|
||||
> **Out of scope — Buch-Projekt (kein Code-Auftrag).** Inhalt unverändert aus der Ur-Fassung übernommen; Ausführung nur mit separatem Auftrag.
|
||||
|
||||
1. Regel + Inverse-Map (ungerade Vorgänger: `(n-1)/3` falls ganz und ungerade) aus Veritasium/Numberphile.
|
||||
2. Hailstone / total stopping time / max excursion als Metriken.
|
||||
3. Brute-force bis praktikabler Grenze + Memoization / Bit-Tricks (Videos erwähnen kombinierte Odd-Steps).
|
||||
4. Stochastisches Modell (3/4-Erwartung) vs. Tao-„almost all“.
|
||||
5. Zyklus-Suche und negative Varianten getrennt halten.
|
||||
6. Quellen-IDs oben als Citations beibehalten, nicht durch Video-Narrativ ersetzen.
|
||||
@@ -0,0 +1,45 @@
|
||||
# Knowledgebase — Index (L0)
|
||||
|
||||
> Autoren-KB für das Sachbuch *Die Collatz-Vermutung* · Progressive Disclosure · Stand: 2026-08-29
|
||||
> **Nicht im PDF.**
|
||||
|
||||
## First Source
|
||||
|
||||
**Diese Datei ist die erste Informationsquelle** nach always-on Rules (`AGENTS.md` + Schreibkonventionen-Import).
|
||||
|
||||
Fakten, „wo steht das?“, Terminologie-Ort und Task-Routing kommen von hier. Kapitel und Skills nur nach Link. **Nicht** den KB-Tree dumpen.
|
||||
|
||||
## Session-Start (Minimal)
|
||||
|
||||
1. `AGENTS.md` + Schreibkonventionen — Command Code lädt das automatisch
|
||||
2. **Diese Datei** — Task-Router oder eine Domain
|
||||
3. `HANDOFF-collatz.md` — nur wenn Session fortsetzen / Slice unfertig
|
||||
4. `docs/kb/<domain>/INDEX.md` — Topic wählen
|
||||
|
||||
**Nicht:** ganzen `docs/kb`-Tree, alle Kapitel oder die Forschungsbasis vorladen.
|
||||
|
||||
## Task-Router
|
||||
|
||||
| Task | Nur laden |
|
||||
|------|-----------|
|
||||
| Fakt fürs Kapitel braucht / Faktenstand prüfen | [00-projekt/forschungsbasis.md](00-projekt/forschungsbasis.md) → dann gezielte `docs/0*.md`-Datei |
|
||||
| Kapitel-Edit / Lektorat / Gegenlese | [01-manuskript/INDEX.md](01-manuskript/stil-ton.md) + Skill |
|
||||
| Fachbegriff einführen / konsistent halten | [01-manuskript/terminologie.md](01-manuskript/terminologie.md) |
|
||||
| „Klingt das nach dem Buch?“ | [01-manuskript/stil-ton.md](01-manuskript/stil-ton.md) |
|
||||
| Repo-Karte / wohin mit der Datei | [00-projekt/repo-karte.md](00-projekt/repo-karte.md) |
|
||||
| Wer darf was ändern | [00-projekt/source-of-truth.md](00-projekt/source-of-truth.md) |
|
||||
| Neuer Agent ohne Repo-Bild | [00-projekt/overview.md](00-projekt/overview.md) |
|
||||
| Video-Narrativ / populäre Darstellung | [02-recherche/video-inhaltskarte.md](02-recherche/video-inhaltskarte.md) |
|
||||
| Kapitelstruktur / Abschluss-Labels | [00-inhaltsverzeichnis.md](../../00-inhaltsverzeichnis.md) |
|
||||
| PDF bauen / QA | Skill `pdf-bauen` / `pdf-print` (Pipeline nur on demand) |
|
||||
| Figur erzeugen | Skill `abbildung` |
|
||||
|
||||
## Domains
|
||||
|
||||
- [00-projekt/](00-projekt/overview.md) — Projekt, Pfade, SoT, Forschungsbasis
|
||||
- [01-manuskript/](01-manuskript/stil-ton.md) — Stil, Terminologie (Pointer; Kanon: `.commandcode/rules/schreibkonventionen.md`)
|
||||
- [02-recherche/](02-recherche/video-inhaltskarte.md) — Quellenmaterial (Video-Inhaltskarte; geprüft gegen `docs/`)
|
||||
|
||||
## Freshness
|
||||
|
||||
- KB-Skelett frisch (2026-08-29). Bei neuem Top-Level-Verzeichnis: repo-karte + source-of-truth mitziehen.
|
||||
@@ -0,0 +1,127 @@
|
||||
# Justfile — PDF-Pipeline für „Coding Agents in der Praxis“
|
||||
#
|
||||
# pandoc + lualatex + KOMA-Template.
|
||||
# TeX Live (KOMA-Script / scrbook) kommt vom Host.
|
||||
#
|
||||
# Outputs:
|
||||
# just pdf → dist/collatz-vermutung.pdf (A4 eBook)
|
||||
# just pdf-print → dist/collatz-vermutung-print.pdf (KDP 6×9 B/W)
|
||||
|
||||
default: pdf
|
||||
|
||||
# resource-path: optional assets + reader content (links im MD)
|
||||
_resource_path := ".:templates:checklists:assets:assets/illustrations:assets/cover"
|
||||
|
||||
# Print: grayscale stage mirrors MD paths (assets/illustrations/… under
|
||||
# build/print-assets/). First path wins → gray before RGB originals.
|
||||
_print_resource_path := "build/print-assets:.:templates:checklists:assets:assets/illustrations:assets/cover"
|
||||
|
||||
assemble:
|
||||
@python3 scripts/assemble_book.py
|
||||
|
||||
pdf-styled: assemble
|
||||
@mkdir -p dist
|
||||
pandoc build/book.md \
|
||||
--pdf-engine=lualatex \
|
||||
--template=pdf/templates/guide.tex \
|
||||
-H pdf/styles/guide-colors.tex \
|
||||
--metadata-file=pdf/metadata.yaml \
|
||||
--lua-filter=pdf/filters/takeaways.lua \
|
||||
--lua-filter=pdf/filters/tables.lua \
|
||||
--resource-path={{_resource_path}} \
|
||||
-V lang=de-DE \
|
||||
-V papersize=a4 \
|
||||
-V colorlinks \
|
||||
--toc \
|
||||
-o dist/collatz-vermutung.pdf
|
||||
|
||||
pdf: pdf-styled
|
||||
|
||||
pdf-draft: assemble
|
||||
@mkdir -p dist
|
||||
pandoc build/book.md \
|
||||
--pdf-engine=lualatex \
|
||||
--template=pdf/templates/guide.tex \
|
||||
-H pdf/styles/guide-colors.tex \
|
||||
--metadata-file=pdf/metadata.yaml \
|
||||
--lua-filter=pdf/filters/takeaways.lua \
|
||||
--lua-filter=pdf/filters/tables.lua \
|
||||
--resource-path={{_resource_path}} \
|
||||
-V lang=de-DE \
|
||||
-V papersize=a4 \
|
||||
-V colorlinks \
|
||||
-V draft=true \
|
||||
--toc \
|
||||
-o dist/collatz-vermutung-draft.pdf
|
||||
|
||||
pdf-plain: assemble
|
||||
@mkdir -p dist
|
||||
pandoc build/book.md \
|
||||
--pdf-engine=lualatex \
|
||||
-V documentclass=scrbook \
|
||||
-V lang=de-DE \
|
||||
-V papersize=a4 \
|
||||
--lua-filter=pdf/filters/tables.lua \
|
||||
--resource-path={{_resource_path}} \
|
||||
--toc \
|
||||
-o dist/collatz-vermutung-plain.pdf
|
||||
|
||||
# --- KDP Paperback Interior (6×9, grayscale) --------------------------------
|
||||
|
||||
print-assets:
|
||||
@python3 scripts/prepare_print_assets.py
|
||||
|
||||
pdf-print: assemble print-assets
|
||||
@mkdir -p dist
|
||||
pandoc build/book.md \
|
||||
--pdf-engine=lualatex \
|
||||
--template=pdf/templates/guide.tex \
|
||||
-H pdf/print/print-colors.tex \
|
||||
--metadata-file=pdf/print/metadata.yaml \
|
||||
--lua-filter=pdf/filters/takeaways.lua \
|
||||
--lua-filter=pdf/filters/tables.lua \
|
||||
--resource-path={{_print_resource_path}} \
|
||||
--syntax-highlighting=monochrome \
|
||||
-V lang=de-DE \
|
||||
-V printmode=true \
|
||||
--toc \
|
||||
-o dist/collatz-vermutung-print.pdf
|
||||
|
||||
# Optional: Ghostscript grayscale/prepress pass (KDP-freundlicher, best-effort)
|
||||
pdf-print-optimize:
|
||||
@test -f dist/collatz-vermutung-print.pdf || (echo "Run just pdf-print first" && exit 1)
|
||||
@command -v gs >/dev/null || (echo "Ghostscript (gs) not found" && exit 1)
|
||||
gs -dBATCH -dNOPAUSE -dSAFER -sDEVICE=pdfwrite \
|
||||
-dCompatibilityLevel=1.5 \
|
||||
-dPDFSETTINGS=/prepress \
|
||||
-dColorConversionStrategy=/Gray \
|
||||
-dProcessColorModel=/DeviceGray \
|
||||
-dEmbedAllFonts=true \
|
||||
-dSubsetFonts=true \
|
||||
-sOutputFile=dist/collatz-vermutung-print-opt.pdf \
|
||||
dist/collatz-vermutung-print.pdf
|
||||
@mv dist/collatz-vermutung-print-opt.pdf dist/collatz-vermutung-print.pdf
|
||||
@echo "optimized → dist/collatz-vermutung-print.pdf"
|
||||
|
||||
# Tight-Loop MD (Manuskript + Templates + Checklisten + AGENTS.md).
|
||||
# Scope/Regeln: .markdownlint-cli2.jsonc — kein PDF.
|
||||
markdownlint:
|
||||
npx --yes markdownlint-cli2@0.18.1
|
||||
|
||||
link-check:
|
||||
python3 scripts/check_md_links.py
|
||||
|
||||
qa:
|
||||
@python3 scripts/check_pdf.py
|
||||
|
||||
qa-print:
|
||||
@python3 scripts/check_pdf.py --pdf dist/collatz-vermutung-print.pdf --mode print
|
||||
|
||||
all: pdf qa
|
||||
|
||||
all-print: pdf-print qa-print
|
||||
|
||||
clean:
|
||||
@rm -rf build
|
||||
@rm -f dist/*.pdf dist/*.aux dist/*.log dist/*.out dist/*.toc
|
||||
@echo "cleaned build/ and dist/*.pdf"
|
||||
@@ -0,0 +1,26 @@
|
||||
% ueber-den-autor.tex — Backmatter, mit TOC-Eintrag
|
||||
\clearpage
|
||||
\thispagestyle{plain}
|
||||
\chapter*{Über den Autor}
|
||||
\addcontentsline{toc}{chapter}{Über den Autor}
|
||||
\markboth{Über den Autor}{Über den Autor}
|
||||
|
||||
Martin Richardt studierte Mathematik und Informatik mit Schwerpunkt
|
||||
Neuroinformatik. Seit rund 35~Jahren arbeitet er in der IT als
|
||||
Softwareentwickler.
|
||||
|
||||
Anfang der 1990er-Jahre sammelte er praktische Erfahrung mit klassischen
|
||||
Machine-Learning-Verfahren, darunter mehrschichtige Perzeptronen und
|
||||
Backpropagation. Später realisierte er eine rotationsunabhängige
|
||||
optische Zeichenerkennung (OCR) auf Basis von Support Vector Machines.
|
||||
|
||||
Diesen Wandel -- von überschaubaren Algorithmen zu großen,
|
||||
datengetriebenen Systemen -- hat er aus der Entwicklerpraxis
|
||||
mitverfolgt. Dieses Buch nutzt genau diesen Blick: auf das, was in
|
||||
heutigen KI-Systemen technisch geschieht, und auf das, was man ihnen
|
||||
nicht zuschreiben sollte.
|
||||
|
||||
\vspace{0.8em}
|
||||
Kontakt: \href{mailto:coding-agents@maatini.space}{coding-agents@maatini.space}
|
||||
|
||||
\clearpage
|
||||
@@ -0,0 +1,450 @@
|
||||
-- tables.lua — PDF table layout for *Coding Agents in der Praxis*
|
||||
--
|
||||
-- Fixes overlapping / overflowing longtable columns:
|
||||
-- 1) Rebalance ColWidth from content (code columns need more room)
|
||||
-- 2) Make inline Code breakable at _, ., -, / inside tables
|
||||
-- 3) Scale font + tabcolsep by column count for wide tables
|
||||
--
|
||||
-- Ported from the sister-project pipeline (ki-codex).
|
||||
-- Only affects LaTeX/PDF output.
|
||||
|
||||
local function is_latex()
|
||||
return FORMAT:match("latex") ~= nil
|
||||
end
|
||||
|
||||
local function escape_tex(s)
|
||||
s = s:gsub("\\", "\\textbackslash{}")
|
||||
s = s:gsub("([&%%%$#_{}])", "\\%1")
|
||||
s = s:gsub("~", "\\textasciitilde{}")
|
||||
s = s:gsub("%^", "\\textasciicircum{}")
|
||||
return s
|
||||
end
|
||||
|
||||
--- Breakable monospace: allow line breaks at token separators and camelCase.
|
||||
-- Without this, pure camelCase IDs (e.g. allowManagedPermissionRulesOnly)
|
||||
-- overflow p-columns and paint over the next table column.
|
||||
local function breakable_texttt(text)
|
||||
local s = escape_tex(text)
|
||||
s = s:gsub("\\_", "\\_\\allowbreak{}")
|
||||
s = s:gsub("%.", ".\\allowbreak{}")
|
||||
s = s:gsub("%-", "-\\allowbreak{}")
|
||||
s = s:gsub("/", "/\\allowbreak{}")
|
||||
-- camelCase / PascalCase: break before each capital run
|
||||
s = s:gsub("(%l)(%u)", "%1\\allowbreak{}%2")
|
||||
-- acronym + word (HTTPSConnection → HTTPS + Connection)
|
||||
s = s:gsub("(%u)(%u%l)", "%1\\allowbreak{}%2")
|
||||
return pandoc.RawInline("latex", "\\texttt{" .. s .. "}")
|
||||
end
|
||||
|
||||
local function make_code_breakable(blocks)
|
||||
return pandoc.walk_block(pandoc.Div(blocks), {
|
||||
Code = function(el)
|
||||
return breakable_texttt(el.text)
|
||||
end,
|
||||
}).content
|
||||
end
|
||||
|
||||
local function walk_cell_contents(cell, fn)
|
||||
if cell.contents then
|
||||
cell.contents = fn(cell.contents)
|
||||
end
|
||||
end
|
||||
|
||||
local function for_each_cell(tbl, fn)
|
||||
if tbl.head and tbl.head.rows then
|
||||
for _, row in ipairs(tbl.head.rows) do
|
||||
for j, cell in ipairs(row.cells) do
|
||||
fn(cell, j)
|
||||
end
|
||||
end
|
||||
end
|
||||
if tbl.bodies then
|
||||
for _, body in ipairs(tbl.bodies) do
|
||||
if body.head then
|
||||
for _, row in ipairs(body.head) do
|
||||
for j, cell in ipairs(row.cells) do
|
||||
fn(cell, j)
|
||||
end
|
||||
end
|
||||
end
|
||||
if body.body then
|
||||
for _, row in ipairs(body.body) do
|
||||
for j, cell in ipairs(row.cells) do
|
||||
fn(cell, j)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if tbl.foot and tbl.foot.rows then
|
||||
for _, row in ipairs(tbl.foot.rows) do
|
||||
for j, cell in ipairs(row.cells) do
|
||||
fn(cell, j)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function collect_column_stats(tbl, ncols)
|
||||
local plain = {}
|
||||
local code = {}
|
||||
for i = 1, ncols do
|
||||
plain[i] = 0
|
||||
code[i] = 0
|
||||
end
|
||||
|
||||
for_each_cell(tbl, function(cell, j)
|
||||
if j < 1 or j > ncols then
|
||||
return
|
||||
end
|
||||
local text = pandoc.utils.stringify(cell) or ""
|
||||
if #text > plain[j] then
|
||||
plain[j] = #text
|
||||
end
|
||||
pandoc.walk_block(pandoc.Div(cell.contents or {}), {
|
||||
Code = function(el)
|
||||
if #el.text > code[j] then
|
||||
code[j] = #el.text
|
||||
end
|
||||
end,
|
||||
})
|
||||
end)
|
||||
|
||||
return plain, code
|
||||
end
|
||||
|
||||
local function rebalance_widths(ncols, plain, code)
|
||||
if ncols < 1 then
|
||||
return {}
|
||||
end
|
||||
|
||||
local weights = {}
|
||||
local has_code = {}
|
||||
for i = 1, ncols do
|
||||
local p = plain[i] or 0
|
||||
local c = code[i] or 0
|
||||
has_code[i] = c > 0
|
||||
-- Monospace is wider than proportional body text.
|
||||
weights[i] = math.max(p, c * 1.45, 4)
|
||||
end
|
||||
|
||||
local min_w = math.max(0.08, 0.72 / ncols)
|
||||
local max_w = 0.50
|
||||
if ncols >= 5 then
|
||||
max_w = 0.38
|
||||
end
|
||||
if ncols >= 6 then
|
||||
max_w = 0.30
|
||||
min_w = math.max(0.07, 0.68 / ncols)
|
||||
end
|
||||
if ncols >= 8 then
|
||||
max_w = 0.22
|
||||
min_w = math.max(0.06, 0.64 / ncols)
|
||||
end
|
||||
|
||||
-- Code-heavy columns need a floor so IDs don't spill into neighbors.
|
||||
local code_floor = 0.15
|
||||
if ncols >= 5 then
|
||||
code_floor = 0.185
|
||||
end
|
||||
if ncols >= 6 then
|
||||
code_floor = 0.13
|
||||
end
|
||||
|
||||
local sum = 0
|
||||
for i = 1, ncols do
|
||||
sum = sum + weights[i]
|
||||
end
|
||||
if sum <= 0 then
|
||||
sum = ncols
|
||||
for i = 1, ncols do
|
||||
weights[i] = 1
|
||||
end
|
||||
end
|
||||
|
||||
local widths = {}
|
||||
for i = 1, ncols do
|
||||
local w = weights[i] / sum
|
||||
local floor = min_w
|
||||
if has_code[i] then
|
||||
floor = math.max(floor, code_floor)
|
||||
end
|
||||
if w < floor then
|
||||
w = floor
|
||||
end
|
||||
if w > max_w then
|
||||
w = max_w
|
||||
end
|
||||
widths[i] = w
|
||||
end
|
||||
|
||||
-- Renormalize; if sum drifts, scale then re-clamp lightly.
|
||||
for _ = 1, 4 do
|
||||
local s = 0
|
||||
for i = 1, ncols do
|
||||
s = s + widths[i]
|
||||
end
|
||||
if s <= 0 then
|
||||
break
|
||||
end
|
||||
local factor = 1.0 / s
|
||||
local again = false
|
||||
for i = 1, ncols do
|
||||
widths[i] = widths[i] * factor
|
||||
local floor = min_w
|
||||
if has_code[i] then
|
||||
floor = math.max(floor, math.min(code_floor, 0.95 / ncols))
|
||||
end
|
||||
if widths[i] < floor * 0.98 then
|
||||
widths[i] = floor
|
||||
again = true
|
||||
end
|
||||
end
|
||||
if not again then
|
||||
-- final normalize without clamp
|
||||
s = 0
|
||||
for i = 1, ncols do
|
||||
s = s + widths[i]
|
||||
end
|
||||
if s > 0 then
|
||||
for i = 1, ncols do
|
||||
widths[i] = widths[i] / s
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Round to 4 decimals; fix residual on last column.
|
||||
local acc = 0
|
||||
for i = 1, ncols - 1 do
|
||||
widths[i] = math.floor(widths[i] * 10000 + 0.5) / 10000
|
||||
acc = acc + widths[i]
|
||||
end
|
||||
widths[ncols] = math.max(0.05, 1.0 - acc)
|
||||
|
||||
return widths
|
||||
end
|
||||
|
||||
local function apply_widths(tbl, widths)
|
||||
for i, colspec in ipairs(tbl.colspecs) do
|
||||
local align = colspec[1]
|
||||
local w = widths[i]
|
||||
if w and w > 0 then
|
||||
tbl.colspecs[i] = { align, w }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function max_plain_len(plain)
|
||||
local m = 0
|
||||
for _, v in ipairs(plain) do
|
||||
if v > m then
|
||||
m = v
|
||||
end
|
||||
end
|
||||
return m
|
||||
end
|
||||
|
||||
local function is_print_mode()
|
||||
-- Set via pandoc -V printmode=true (just pdf-print)
|
||||
if PANDOC_WRITER_OPTIONS and PANDOC_WRITER_OPTIONS.variables then
|
||||
local v = PANDOC_WRITER_OPTIONS.variables["printmode"]
|
||||
if v == true or v == "true" or v == "yes" or v == "1" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
local env = os.getenv("PRINT_MODE")
|
||||
return env == "1" or env == "true"
|
||||
end
|
||||
|
||||
local function wrap_style(ncols, max_cell, print_mode)
|
||||
-- Returns (font_cmd or nil, tabcolsep or nil)
|
||||
-- Print (6×9): narrower text block → slightly more aggressive scaling
|
||||
if print_mode then
|
||||
if ncols >= 6 then
|
||||
return "\\scriptsize", "1.6pt"
|
||||
end
|
||||
if ncols >= 5 then
|
||||
return "\\scriptsize", "1.8pt"
|
||||
end
|
||||
if ncols >= 4 then
|
||||
-- 4-col mapping tables (paths + product names) need room, not padding
|
||||
return "\\footnotesize", "2.2pt"
|
||||
end
|
||||
if ncols >= 3 then
|
||||
if max_cell >= 70 then
|
||||
return "\\footnotesize", "2.6pt"
|
||||
end
|
||||
return "\\small", "3.0pt"
|
||||
end
|
||||
if ncols == 2 and max_cell >= 100 then
|
||||
return "\\small", "3.2pt"
|
||||
end
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
if ncols >= 6 then
|
||||
return "\\footnotesize", "2.5pt"
|
||||
end
|
||||
if ncols >= 4 then
|
||||
return "\\small", "3.2pt"
|
||||
end
|
||||
if ncols >= 3 and max_cell >= 90 then
|
||||
return "\\small", "3.8pt"
|
||||
end
|
||||
if ncols == 2 and max_cell >= 160 then
|
||||
return "\\small", nil
|
||||
end
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
--- Normalize header cell text for Do/Avoid detection.
|
||||
local function norm_header(s)
|
||||
s = (s or ""):lower()
|
||||
s = s:gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
|
||||
return s
|
||||
end
|
||||
|
||||
--- Classify a header cell: "do", "avoid", or nil.
|
||||
local function classify_do_avoid_cell(text)
|
||||
local t = norm_header(text)
|
||||
if t == "" then
|
||||
return nil
|
||||
end
|
||||
-- Do this / Do / Do this instead
|
||||
if t:match("^do%s*this") or t == "do" or t:match("^do%s") then
|
||||
return "do"
|
||||
end
|
||||
if t:match("^avoid") then
|
||||
return "avoid"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Inspect first header row: returns mode "doavoid" | "plain" | nil (no head)
|
||||
local function header_mode(tbl)
|
||||
if not tbl.head or not tbl.head.rows or #tbl.head.rows < 1 then
|
||||
return nil, {}
|
||||
end
|
||||
local row = tbl.head.rows[1]
|
||||
if not row or not row.cells then
|
||||
return nil, {}
|
||||
end
|
||||
local classes = {}
|
||||
local saw_do, saw_avoid = false, false
|
||||
for j, cell in ipairs(row.cells) do
|
||||
local text = pandoc.utils.stringify(cell) or ""
|
||||
local c = classify_do_avoid_cell(text)
|
||||
classes[j] = c
|
||||
if c == "do" then
|
||||
saw_do = true
|
||||
end
|
||||
if c == "avoid" then
|
||||
saw_avoid = true
|
||||
end
|
||||
end
|
||||
if saw_do or saw_avoid then
|
||||
return "doavoid", classes
|
||||
end
|
||||
return "plain", classes
|
||||
end
|
||||
|
||||
--- Inject \cellcolor into each header cell (colortbl).
|
||||
-- Pandoc wraps wide-table cells in minipage → \rowcolor (\noalign) is illegal;
|
||||
-- \cellcolor inside the minipage still tints the cell background.
|
||||
local function prepend_cellcolor(cell, color)
|
||||
local prefix = pandoc.RawInline("latex", "\\cellcolor{" .. color .. "}")
|
||||
if cell.contents and #cell.contents > 0 then
|
||||
local first = cell.contents[1]
|
||||
if first and (first.t == "Para" or first.t == "Plain") and first.content then
|
||||
table.insert(first.content, 1, prefix)
|
||||
else
|
||||
table.insert(cell.contents, 1, pandoc.Plain({ prefix }))
|
||||
end
|
||||
else
|
||||
cell.contents = { pandoc.Plain({ prefix }) }
|
||||
end
|
||||
end
|
||||
|
||||
local function style_header_row(tbl, mode, classes)
|
||||
if not tbl.head or not tbl.head.rows or #tbl.head.rows < 1 then
|
||||
return
|
||||
end
|
||||
local row = tbl.head.rows[1]
|
||||
if not row or not row.cells or #row.cells < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
for j, cell in ipairs(row.cells) do
|
||||
local color = "guidetablehead"
|
||||
if mode == "doavoid" then
|
||||
if classes[j] == "do" then
|
||||
color = "guidedohead"
|
||||
elseif classes[j] == "avoid" then
|
||||
color = "guideavoidhead"
|
||||
end
|
||||
end
|
||||
prepend_cellcolor(cell, color)
|
||||
end
|
||||
end
|
||||
|
||||
function Table(tbl)
|
||||
if not is_latex() then
|
||||
return nil
|
||||
end
|
||||
|
||||
local ncols = #tbl.colspecs
|
||||
if ncols < 1 then
|
||||
return nil
|
||||
end
|
||||
|
||||
local print_mode = is_print_mode()
|
||||
local plain, code = collect_column_stats(tbl, ncols)
|
||||
local widths = rebalance_widths(ncols, plain, code)
|
||||
apply_widths(tbl, widths)
|
||||
|
||||
-- Breakable code only inside this table's cells.
|
||||
for_each_cell(tbl, function(cell, _)
|
||||
walk_cell_contents(cell, make_code_breakable)
|
||||
end)
|
||||
|
||||
-- Colored headers (booktabs + colortbl); Do/Avoid get dual tints
|
||||
local mode, classes = header_mode(tbl)
|
||||
if mode then
|
||||
style_header_row(tbl, mode, classes)
|
||||
end
|
||||
|
||||
local font_cmd, sep = wrap_style(ncols, max_plain_len(plain), print_mode)
|
||||
-- Always wrap multi-column tables: emergencystretch reduces overfull
|
||||
-- hboxes in narrow p-columns (German compounds, long headers).
|
||||
if ncols < 2 and not font_cmd and not sep then
|
||||
return tbl
|
||||
end
|
||||
|
||||
local open = "\\begingroup"
|
||||
if font_cmd then
|
||||
open = open .. font_cmd
|
||||
end
|
||||
if sep then
|
||||
open = open .. "\\setlength{\\tabcolsep}{" .. sep .. "}"
|
||||
end
|
||||
local stretch = print_mode and "3.2em" or "2.5em"
|
||||
if ncols >= 2 then
|
||||
open = open .. "\\sloppy\\setlength{\\emergencystretch}{" .. stretch .. "}"
|
||||
end
|
||||
-- Print: ragged-right p-columns avoid word-spacing collapse that looks like
|
||||
-- overlapping headers when long German compounds / paths refuse to break.
|
||||
if print_mode and ncols >= 3 then
|
||||
open = open
|
||||
.. "\\raggedright"
|
||||
.. "\\hyphenpenalty=50\\exhyphenpenalty=50"
|
||||
.. "\\setlength{\\LTleft}{0pt}\\setlength{\\LTright}{0pt}"
|
||||
end
|
||||
|
||||
return {
|
||||
pandoc.RawBlock("latex", open),
|
||||
tbl,
|
||||
pandoc.RawBlock("latex", "\\endgroup"),
|
||||
}
|
||||
end
|
||||
@@ -0,0 +1,82 @@
|
||||
-- takeaways.lua — wrap chapter closing sections in tcolorbox environments
|
||||
--
|
||||
-- Matches level-2 headers (##):
|
||||
-- "Key Takeaways" → guidetakeaways
|
||||
-- "Praktische nächste Schritte" → guidenext
|
||||
--
|
||||
-- Boxes are defined in guide-preamble.tex / print-preamble.tex.
|
||||
-- Only affects LaTeX/PDF output. Heading stays for structure; box has own title.
|
||||
|
||||
local function is_latex()
|
||||
return FORMAT:match("latex") ~= nil
|
||||
end
|
||||
|
||||
local function header_kind(el)
|
||||
if el.t ~= "Header" or el.level ~= 2 then
|
||||
return nil
|
||||
end
|
||||
local title = pandoc.utils.stringify(el) or ""
|
||||
-- tolerate optional trailing punctuation / whitespace
|
||||
local norm = title:gsub("%s+", " "):gsub("^%s+", ""):gsub("%s+$", "")
|
||||
if norm:match("^[Kk]ey [Tt]akeaways") then
|
||||
return "takeaways"
|
||||
end
|
||||
if norm:match("^[Pp]raktische [Nn]ächste [Ss]chritte")
|
||||
or norm:match("^[Pp]raktische [Nn]aechste [Ss]chritte") then
|
||||
return "next"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function env_for(kind)
|
||||
if kind == "takeaways" then
|
||||
return "guidetakeaways"
|
||||
end
|
||||
if kind == "next" then
|
||||
return "guidenext"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function Pandoc(doc)
|
||||
if not is_latex() then
|
||||
return nil
|
||||
end
|
||||
|
||||
local blocks = doc.blocks
|
||||
local out = {}
|
||||
local i = 1
|
||||
local n = #blocks
|
||||
|
||||
while i <= n do
|
||||
local b = blocks[i]
|
||||
local kind = header_kind(b)
|
||||
if kind then
|
||||
local env = env_for(kind)
|
||||
-- Skip visible duplicate title: box title carries the label.
|
||||
-- Keep a hypertarget/bookmark-friendly phantom if header has identifier.
|
||||
local id = b.identifier
|
||||
if id and id ~= "" then
|
||||
table.insert(out, pandoc.RawBlock("latex", "\\hypertarget{" .. id .. "}{}\\label{" .. id .. "}"))
|
||||
end
|
||||
table.insert(out, pandoc.RawBlock("latex", "\\begin{" .. env .. "}"))
|
||||
i = i + 1
|
||||
while i <= n do
|
||||
local nb = blocks[i]
|
||||
if nb.t == "Header" and nb.level <= 2 then
|
||||
break
|
||||
end
|
||||
table.insert(out, nb)
|
||||
i = i + 1
|
||||
end
|
||||
table.insert(out, pandoc.RawBlock("latex", "\\end{" .. env .. "}"))
|
||||
-- do not increment past the next header; loop will handle it
|
||||
else
|
||||
table.insert(out, b)
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
|
||||
doc.blocks = out
|
||||
return doc
|
||||
end
|
||||
@@ -0,0 +1,131 @@
|
||||
% impressum.tex — Copyright- / Impressumsseite (inkl. KI-Transparenz)
|
||||
\clearpage
|
||||
\thispagestyle{empty}
|
||||
\begingroup
|
||||
\small\color{nexttokentext}%
|
||||
\raggedright
|
||||
|
||||
{\sffamily\color{nexttokenblue}\Large\bfseries Impressum\par}
|
||||
\vspace{0.8em}
|
||||
|
||||
{\sffamily\bfseries Coding Agents in der Praxis\par}
|
||||
{\itshape Ein pragmatischer Leitfaden zum effektiven Einsatz von
|
||||
LLM-basierten Coding-Agents unter Berücksichtigung ihrer Limitationen\par}
|
||||
|
||||
\vspace{1.0em}
|
||||
|
||||
{\sffamily © 2026 Martin Richardt\par}
|
||||
Alle Rechte vorbehalten.\par
|
||||
|
||||
\vspace{0.6em}
|
||||
|
||||
1.~Auflage 2026\par
|
||||
Autor: Martin Richardt\par
|
||||
Selbstverlag / Freiberufler\par
|
||||
Vertrieb u.\,a.\ über Amazon Kindle Direct Publishing (KDP)\par
|
||||
Stand: August 2026 (aktuelle Coding-Agents mit Tool-Use).\par
|
||||
|
||||
\vspace{0.8em}
|
||||
|
||||
{\sffamily\bfseries Begleitmaterial und Vorlagen\par}
|
||||
\vspace{0.3em}
|
||||
Die lebenden und vollständigen Templates und Checklisten liegen im
|
||||
\textbf{Begleit-Service}
|
||||
(\url{https://books.maatini.space/projects/coding-agents-praxis/};
|
||||
Stand \& Drift, Errata, Material-ZIPs, Hilfe, Feedback)
|
||||
sowie im Buch-Repository unter \texttt{templates/} und
|
||||
\texttt{checklists/}.
|
||||
Kontakt: \href{mailto:coding-agents@maatini.space}{coding-agents@maatini.space}.
|
||||
Die wichtigsten Vorlagen sind zur Standalone-Nutzung zusätzlich im
|
||||
\textbf{Anhang~A} abgedruckt.
|
||||
Eine kompakte Stack-Orientierung (Sprachen/Frameworks nach Anwendungsfall)
|
||||
steht im \textbf{Anhang~B} (Snapshot; Updates im Begleit-Service und Buch-Repo).\par
|
||||
|
||||
\vspace{0.8em}
|
||||
|
||||
{\sffamily\bfseries Anbieter und Kontakt\par}
|
||||
\vspace{0.3em}
|
||||
Martin Richardt\par
|
||||
c/o Autorenglück \#26550\par
|
||||
Albert-Einstein-Str. 47\par
|
||||
02977 Hoyerswerda\par
|
||||
Deutschland\par
|
||||
\vspace{0.3em}
|
||||
E-Mail: \href{mailto:coding-agents@maatini.space}{coding-agents@maatini.space}\par
|
||||
|
||||
\vspace{1.0em}
|
||||
|
||||
Dieses Werk ist urheberrechtlich geschützt.
|
||||
Jede Verwertung außerhalb der engen Grenzen des Urheberrechtsgesetzes
|
||||
ist ohne Zustimmung des Autors unzulässig und strafbar. Das gilt
|
||||
insbesondere für Vervielfältigungen, Übersetzungen, Mikroverfilmungen
|
||||
und die Einspeicherung und Verarbeitung in elektronischen Systemen.
|
||||
Kurze Zitate und interne Weitergabe im Team sind gestattet.\par
|
||||
|
||||
\vspace{0.8em}
|
||||
|
||||
Die Deutsche Nationalbibliothek verzeichnet diese Publikation in der
|
||||
Deutschen Nationalbibliografie; detaillierte bibliografische Daten
|
||||
sind im Internet über \url{http://dnb.d-nb.de} abrufbar.\par
|
||||
|
||||
% ISBN: bei Vergabe hier ergänzen
|
||||
|
||||
\vspace{1.0em}
|
||||
|
||||
{\sffamily\bfseries Herstellung und KI-Hinweis\par}
|
||||
\vspace{0.3em}
|
||||
Umschlaggestaltung: Martin Richardt\par
|
||||
Umschlag- und Innenbildmaterial (falls vorhanden): mit generativen
|
||||
Bildmodellen erzeugt und vom Autor ausgewählt bzw.\ kuratiert\par
|
||||
Satz und Layout: Martin Richardt\par
|
||||
\vspace{0.4em}
|
||||
Das Manuskript entstand unter Einsatz generativer KI
|
||||
(u.\,a.\ Entwurf und stilistische Ausarbeitung).
|
||||
Der Autor hat den Text fachlich geprüft, überarbeitet und
|
||||
trägt die redaktionelle Verantwortung.\par
|
||||
\vspace{0.3em}
|
||||
Cover und Abbildungen im Buchinhalt können KI-generiert sein.
|
||||
Der Fließtext enthält KI-generierte Anteile, die vom Autor
|
||||
überarbeitet und freigegeben wurden.\par
|
||||
\vspace{0.3em}
|
||||
Die Abbildungen sind konzeptionelle Visualisierungen, keine exakten
|
||||
technischen Schemata. Sie wurden mit generativen Bildmodellen erzeugt
|
||||
und vom Autor ausgewählt bzw.\ nachbearbeitet. Trotz sorgfältiger
|
||||
Auswahl können aufgrund der aktuellen technischen Grenzen solcher
|
||||
Modelle Artefakte -- insbesondere bei Schriftzügen und feinen
|
||||
Beschriftungen -- verbleiben. Maßgeblich für das Verständnis ist
|
||||
stets der begleitende Text.\par
|
||||
|
||||
\vspace{0.8em}
|
||||
|
||||
{\sffamily\bfseries Haftungsausschluss\par}
|
||||
\vspace{0.3em}
|
||||
Trotz sorgfältiger inhaltlicher Kontrolle übernimmt der Autor keine
|
||||
Haftung für die Richtigkeit, Vollständigkeit und Aktualität der
|
||||
Inhalte. Installationswege, Einstellungen und Benutzeroberflächen von
|
||||
Coding-Agents und verwandten Diensten (u.\,a.\ Aider, Claude Code,
|
||||
Codex, Cursor, Grok Build) können sich ändern; maßgeblich ist
|
||||
die aktuelle Produktdokumentation. Das Buch ersetzt keine fachliche
|
||||
Beratung -- insbesondere keine Rechts-, Datenschutz- (DSGVO),
|
||||
Compliance- (u.\,a.\ EU AI Act), Sicherheits- oder Vertragsberatung
|
||||
im Unternehmen.\par
|
||||
\vspace{0.35em}
|
||||
Beispiele, Konfigurationen und Workflows in diesem Werk dienen der
|
||||
Schulung und Orientierung. Für Schäden aus der Anwendung -- einschließlich
|
||||
automatisierter Agenten-Aktionen, fehlerhafter Freigaben oder ungeeigneter
|
||||
Policies -- übernimmt der Autor keine Haftung. KI-generierter Code und
|
||||
Vorschläge erfordern menschliche Prüfung; Merge, Release und
|
||||
Produktionszugriff bleiben in der Verantwortung der Anwendenden bzw.\
|
||||
ihrer Organisation. Produkt- und Rechtslage können sich ändern; Stand
|
||||
dieses Buchs ist Mitte/Ende 2026.\par
|
||||
|
||||
\vspace{0.6em}
|
||||
|
||||
{\sffamily\color{nexttokenslate}\footnotesize
|
||||
Produktnamen (Aider, Anthropic, Claude, Codex, Cursor, Grok, OpenAI,
|
||||
xAI, Amazon, Kindle Direct Publishing u.\,a.) sind Eigentum der jeweiligen
|
||||
Rechteinhaber. Dies ist keine offizielle Dokumentation der genannten
|
||||
Anbieter.\par}
|
||||
|
||||
\endgroup
|
||||
\clearpage
|
||||
@@ -0,0 +1,15 @@
|
||||
title: "Die Collatz-Vermutung"
|
||||
subtitle: "Die einfachste ungelöste Frage der Mathematik — ein Sachbuch für alle"
|
||||
author: "Martin Richardt"
|
||||
date: "August 2026"
|
||||
lang: de-DE
|
||||
documentclass: scrbook
|
||||
# DIV=11: großzügigere Ränder / Typografie-Outfit (war DIV=13)
|
||||
classoption: [11pt, a4paper, oneside, openany, DIV=11]
|
||||
# Body 11 pt · linestretch 1.15 ≈ 12,7 pt leading (Premium-Lesbarkeit)
|
||||
linestretch: "1.15"
|
||||
has-frontmatter: true
|
||||
toc-title: "Inhaltsverzeichnis"
|
||||
# LaTeX tocdepth: 0=nur Kapitel, 1=Kapitel+## (kuratiert via {.unlisted}), 2=+###
|
||||
# Ziel IV: ca. 2–3 Seiten; Satellite-## mit {.unlisted} (Key Takeaways bereits unlisted)
|
||||
toc-depth: 1
|
||||
@@ -0,0 +1,86 @@
|
||||
# Print-Interior QA-Notes (KDP 6×9)
|
||||
|
||||
Stand: KDP-Ränder (Footer + Header) aus Schwesterprojekt `ki-eit` nachgezogen; Cover-Blank-Fixes und Praxis-Metadaten bleiben.
|
||||
|
||||
## Build
|
||||
|
||||
| Item | Wert |
|
||||
|------|------|
|
||||
| Output | `dist/coding-agents-praxis-print.pdf` |
|
||||
| Trim | 6 × 9 in (432 × 648 pt) |
|
||||
| Seiten | **300** (Soft-QA 120–320; eBook A4 separat) |
|
||||
| Farbe | Grayscale (Palette + Assets); Code `--syntax-highlighting=monochrome` (Fett/Kursiv, kein RGB) |
|
||||
| Schriften | TeX Gyre Heros **Scale=1.0** + DejaVu Sans Mono, embedded |
|
||||
| PDF | 1.5, LuaTeX; optional `just pdf-print-optimize` (GS Gray/prepress) |
|
||||
| Ränder | inner **0,65"** · outer **0,60"** · top **0,70"** · bottom **1,00"** (Textkörper) |
|
||||
| Kopf/Fuß | headsep **0,12"** · footskip **0,30"** (Header-Ink ≈ **0,45"** · Seitenzahl-Ink ≈ **0,65"** vom Trim) |
|
||||
| Titelseite | Cover im **0,30"**-Safe-Frame (KDP-Außen ≥ 0,25") |
|
||||
| Figuren | Gin `width=0,87\linewidth` → 1280 px ≈ **300 DPI** (Textbreite 4,75") |
|
||||
| Typo | Body **10 pt** · linestretch **1,22** (~14,6 pt) · Box/Code/Tabelle **9 pt** |
|
||||
|
||||
**Footer-Mechanik:** geometry-`bottom` = Textkörper→Trim; Seitenzahl bei `bottom − footskip`. Früher bottom 0,65" + footskip 0,28" → Ink nur ≈0,33″ (KDP-Minimum 0,5″ verfehlt). Jetzt bottom 1,00" + footskip 0,30" → Ink ≈0,65–0,74″.
|
||||
|
||||
**Header-Mechanik:** Bei festem `top` sitzt der Kolumnentitel oberhalb; kleineres `headsep` schiebt den Header nach unten. Früher headsep 0,28" → Ink ≈0,28″. Jetzt headsep 0,12" → Ink ≈0,44″ (Ziel 0,40–0,50″).
|
||||
|
||||
## KDP-Scorecard (Interior)
|
||||
|
||||
| Kriterium | KDP | Status |
|
||||
|-----------|-----|--------|
|
||||
| Trim 6×9, kein Bleed | ja | ✅ |
|
||||
| Gutter ≥ 0,375" (24–150 S.) | 0,65" | ✅ für dünnere Bände; ~290 S. → KDP empfiehlt oft mehr Gutter (Follow-up) |
|
||||
| Außen/oben/unten ≥ 0,25" | 0,60 / 0,70 / Text 1,00 · Footer-Ink ≈ 0,65 | ✅ |
|
||||
| Titelseite ≥ 0,25" | 0,30" | ✅ |
|
||||
| Fonts embedded | ja | ✅ |
|
||||
| Min. Schrift ≥ 7 pt | Body 10 / Box·Code 9 | ✅ |
|
||||
| Bilder ≥ 300 DPI | Gin 0,87 + Cover ≥ 1620 px | ✅ Pipeline-Ziel (Cover ggf. Upscale-WARN) |
|
||||
| Cover-PDF (Spine/Bleed) | separat | ❌ out of scope |
|
||||
|
||||
## Änderungs-Checkliste (Pipeline)
|
||||
|
||||
- [x] Parallele Print-Pipeline (`just pdf-print` / `qa-print`)
|
||||
- [x] Skill `pdf-print` + Command `/pdf-print`
|
||||
- [x] eBook unverändert (A4, Farbe)
|
||||
- [x] twoside, openany, Seitenzahlen außen unten
|
||||
- [x] Cover-Titelseite mit KDP-Safe-Frame (0,30")
|
||||
- [x] Grayscale-Assets via `prepare_print_assets.py`
|
||||
- [x] Code monochrome (`--syntax-highlighting=monochrome` in `just pdf-print`; eBook bleibt farbig)
|
||||
- [x] Tabellen-Filter Print-Modus (`-V printmode=true`)
|
||||
- [x] Figurenbreite für ~300 DPI bei 1280-px-Quellen
|
||||
- [ ] Cover-Print-Quelle `assets/cover/cover-front-print.jpg` (Fallback: cover-front.jpg + Upscale)
|
||||
- [x] Optional GS-Optimize (`just pdf-print-optimize`)
|
||||
|
||||
## Manuelle Nacharbeit empfohlen
|
||||
|
||||
### Abbildungen (B/W-Lesbarkeit)
|
||||
|
||||
Display-DPI ist per Gin abgesichert. Bei scharfer Print-Kritik weiterhin:
|
||||
|
||||
| Priorität | IDs | Warum |
|
||||
|-----------|-----|--------|
|
||||
| Hoch | K-03, K-08, K-09, K-12 | Farbe oft Unterscheidungskanal (U-Kurve, Tiers, Disclosure, Multi-Agent) |
|
||||
| Mittel | K-05, M-02, M-10, M-09 | dichte Labels / Isolation |
|
||||
| OK | K-01, K-07 u. a. | oft strukturstark ohne reine Farbcodierung |
|
||||
|
||||
Maßnahmen: SVG neu rendern (Schraffur statt Farbe) oder Imagine ≥ 1800 px Breite, dann `just print-assets` + `just pdf-print`.
|
||||
|
||||
### Cover-Quelle
|
||||
|
||||
- Aktuell: Fallback `cover-front.jpg` (klein) → Pipeline upscaled für Interim.
|
||||
- Besser: natives `assets/cover/cover-front-print.jpg` ≥ 1800×2700 ohne Upscale.
|
||||
|
||||
### Sonstiges
|
||||
|
||||
- **Seite 2** nach Titelseite: leeres Verso — üblich im Paperback.
|
||||
- **KDP-Außenumschlag** (Bleed + Spine) ist **nicht** dieses Interior.
|
||||
- PDF/X-1a: nicht erzwungen; `pdf-print-optimize` ist best-effort Grayscale.
|
||||
- **Breite Tabellen:** Anhang B / Matrizen — `tables.lua` skaliert Print ab 3–4 Spalten aggressiver.
|
||||
|
||||
## Kommandos
|
||||
|
||||
```bash
|
||||
just pdf-print # Interior bauen
|
||||
just pdf-print-optimize # optional GS Gray/prepress
|
||||
just qa-print # Checks
|
||||
just all-print # pdf-print + qa-print
|
||||
just pdf # eBook (unabhängig)
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
title: "Coding Agents in der Praxis"
|
||||
subtitle: "Ein pragmatischer Leitfaden zum effektiven Einsatz von LLM-basierten Coding-Agents unter Berücksichtigung ihrer Limitationen"
|
||||
author: "Martin Richardt"
|
||||
date: "August 2026"
|
||||
lang: de-DE
|
||||
documentclass: scrbook
|
||||
# KDP Paperback Interior: 6×9 in, twoside, openany (keine erzwungenen Leerseiten)
|
||||
print-interior: true
|
||||
# KOMA key-value (bare "10.5pt" is ignored by scrbook)
|
||||
classoption:
|
||||
- fontsize=10pt
|
||||
# 10 pt body · nominal baselineskip ~12 pt × 1.22 ≈ 14.6 pt leading
|
||||
linestretch: "1.22"
|
||||
geometry:
|
||||
- paperwidth=6in
|
||||
- paperheight=9in
|
||||
# Professionelle KDP-Ränder (Typeblock ≥0.65″ vom Trim; Gutter > Außen)
|
||||
- inner=0.65in
|
||||
- outer=0.60in
|
||||
- top=0.70in
|
||||
# bottom trägt Textkörper + Footer: Footer-Baseline ≈ bottom − footskip
|
||||
# Glyph-Unterkante Seitenzahl ≥ 0,65″ vom Trim → bottom 1.00, footskip 0.30
|
||||
# (Baseline ≈ 0,70″; 9-pt-Ziffern ~3 pt unter Baseline → ≈ 0,65″ Ink)
|
||||
- bottom=1.00in
|
||||
- headheight=14pt
|
||||
# headsep: Abstand Header-Zone → Textkörper. Bei festem top schiebt kleineres
|
||||
# headsep den Kolumnentitel nach unten (Textkörper bleibt). 0.12in ≈ 8,6 pt
|
||||
# → Header-Ink ≈ 0,45″ vom oberen Trim (war 0,28in → nur ≈ 0,28″, zu eng).
|
||||
- headsep=0.12in
|
||||
- footskip=0.30in
|
||||
has-frontmatter: true
|
||||
toc-title: "Inhaltsverzeichnis"
|
||||
# LaTeX tocdepth: 0=nur Kapitel, 1=Kapitel+## (kuratiert via {.unlisted}), 2=+###
|
||||
toc-depth: 1
|
||||
@@ -0,0 +1,33 @@
|
||||
% print-colors.tex — Grayscale-Palette für KDP-Interior (White Paper)
|
||||
% Gleiche Farbnamen wie guide-colors.tex → Callouts/Templates bleiben kompatibel.
|
||||
% Geladen via Pandoc `-H`. Vorausgesetzt: xcolor (Template lädt es).
|
||||
|
||||
\IfFileExists{xcolor.sty}{\usepackage{xcolor}}{}
|
||||
|
||||
% --- Grayscale-Palette (druckbar, hoher Kontrast) ---------------------------
|
||||
\definecolor{nexttokenblue}{gray}{0.12} % fast schwarz (H1, Kopf)
|
||||
\definecolor{nexttokengold}{gray}{0.38} % mittleres Grau (Linien, Teal-Ersatz)
|
||||
\definecolor{nexttokenburgundy}{gray}{0.22} % dunkles Grau (Legacy)
|
||||
\definecolor{nexttokentext}{gray}{0.08} % Fließtext
|
||||
\definecolor{nexttokenslate}{gray}{0.32} % Zitate, Hinweise
|
||||
\definecolor{nexttokenparchment}{gray}{0.96} % Box-Fond
|
||||
\definecolor{nexttokenlink}{gray}{0.12}
|
||||
|
||||
% Semantik-Tokens (Parität zu eBook; unterscheidbare Grauwerte)
|
||||
\definecolor{guidecoral}{gray}{0.28} % Avoid / Achtung (dunkler)
|
||||
\definecolor{guidedo}{gray}{0.42} % Do-Akzent
|
||||
\definecolor{guidetakeaways}{gray}{0.35} % Takeaways-Balken
|
||||
\definecolor{guidenextaccent}{gray}{0.40} % Next-Balken (≈ Teal-Grau)
|
||||
\definecolor{nexttokensubsection}{gray}{0.22} % H3
|
||||
|
||||
\colorlet{nexttokenblue!soft}{nexttokenblue!18!white}
|
||||
\colorlet{nexttokengold!soft}{nexttokengold!25!white}
|
||||
\colorlet{nexttokenburgundy!soft}{nexttokenburgundy!12!white}
|
||||
\colorlet{guidecoral!soft}{guidecoral!12!white}
|
||||
|
||||
% Tabellen-Header / Do-Avoid (Grayscale; Do etwas heller, Avoid etwas dunkler)
|
||||
\definecolor{guidetablehead}{gray}{0.92}
|
||||
\definecolor{guidedohead}{gray}{0.94}
|
||||
\definecolor{guideavoidhead}{gray}{0.88}
|
||||
\definecolor{guidetakeawaysbg}{gray}{0.96}
|
||||
\definecolor{guidenextbg}{gray}{0.965}
|
||||
@@ -0,0 +1,362 @@
|
||||
% print-preamble.tex — KDP Paperback Interior (6×9, grayscale)
|
||||
% Ersetzt guide-preamble.tex im Print-Build (Template: print-interior: true).
|
||||
%
|
||||
% Layout-Ziel (Professionell / KDP-tauglich):
|
||||
% Body TeX Gyre Heros 10 pt, Leading ~14.5–15 pt
|
||||
% Ränder: inner 0.65" · outer 0.60" · top 0.70" · bottom 1.00"
|
||||
% headsep 0.12" → Kolumnentitel ≈ 0.45" vom oberen Trim (KDP-sicher)
|
||||
% footskip 0.30" → Seitenzahl-Ink ≈ 0.65" vom Trim (KDP-sicher)
|
||||
% Boxen/Tabellen/Code 9 pt; etwas mehr Weißraum um Floats & Callouts
|
||||
|
||||
% ===========================================================================
|
||||
% 0) SPRACHE / SILBENTRENNUNG
|
||||
% ===========================================================================
|
||||
\usepackage[shorthands=off,main=ngerman]{babel}
|
||||
|
||||
% ===========================================================================
|
||||
% 1) FONTS — Sans-Body (echte 10 pt), Mono für Code/Pfade
|
||||
% Scale=1.0: MatchLowercase skaliert Heros auf LM-x-Höhe (~8 pt optisch) — vermeiden
|
||||
% ===========================================================================
|
||||
\directlua{
|
||||
luaotfload.add_fallback("printfb", {"DejaVu Sans:mode=node;"})
|
||||
}
|
||||
\setmainfont{TeX Gyre Heros}[
|
||||
Ligatures=TeX,
|
||||
Scale=1.0,
|
||||
RawFeature={fallback=printfb}
|
||||
]
|
||||
\setsansfont{TeX Gyre Heros}[
|
||||
Ligatures=TeX,
|
||||
Scale=1.0,
|
||||
RawFeature={fallback=printfb}
|
||||
]
|
||||
% DejaVu Sans Mono: gute Unicode-Abdeckung für Dateipfade / CLI
|
||||
\setmonofont{DejaVu Sans Mono}[
|
||||
Scale=0.95,
|
||||
RawFeature={fallback=printfb}
|
||||
]
|
||||
% Body 10 pt + linestretch 1.22 (metadata) → Leading ≈ 14.6 pt
|
||||
% (kein zusätzliches \fontsize{10}{14.5}: würde mit setstretch multiplizieren)
|
||||
|
||||
% Lange URLs umbrechen (Impressum / Links) — vor hyperref im Template geladen
|
||||
\usepackage{xurl}
|
||||
|
||||
% Schmaler 6×9-Spiegel: weniger Overfull-\hbox (lange Pfade/Komposita)
|
||||
\sloppy
|
||||
\setlength{\emergencystretch}{3em}
|
||||
\tolerance=2000
|
||||
|
||||
% ===========================================================================
|
||||
% 2) KOMA-Script Überschriften (Grayscale-Farben aus print-colors.tex)
|
||||
% Chapter ~16.5 pt · Section ~12.5 pt · Subsection ~11 pt
|
||||
% ===========================================================================
|
||||
\addtokomafont{chapter}{\color{nexttokenblue}\sffamily\bfseries\fontsize{16.5}{20}\selectfont}
|
||||
\addtokomafont{section}{\color{nexttokenblue}\sffamily\bfseries\fontsize{12.5}{15}\selectfont}
|
||||
\addtokomafont{subsection}{\color{nexttokensubsection}\sffamily\bfseries\fontsize{11}{13.5}\selectfont}
|
||||
\addtokomafont{disposition}{\normalcolor}
|
||||
|
||||
% Outfit-Parität: etwas mehr Luft (KDP-Ränder unverändert)
|
||||
\RedeclareSectionCommand[beforeskip=1.55\baselineskip,afterskip=.7\baselineskip]{chapter}
|
||||
\RedeclareSectionCommand[beforeskip=1.2\baselineskip,afterskip=.45\baselineskip]{section}
|
||||
\RedeclareSectionCommand[beforeskip=0.9\baselineskip,afterskip=.32\baselineskip]{subsection}
|
||||
|
||||
\renewcommand{\chapterlinesformat}[3]{%
|
||||
\raggedsection
|
||||
#3\par
|
||||
\nobreak\vspace{0.35em}%
|
||||
{\color{nexttokengold}\rule{0.22\textwidth}{1.2pt}}\par
|
||||
\nobreak\vspace{0.4em}%
|
||||
}
|
||||
|
||||
% ===========================================================================
|
||||
% 3) Kopf-/Fußzeile — twoside: außen; Seitenzahl nicht im Gutter
|
||||
% ===========================================================================
|
||||
\usepackage{scrlayer-scrpage}
|
||||
\clearpairofpagestyles
|
||||
\ohead{\headmark}
|
||||
\ihead{}
|
||||
\chead{}
|
||||
\cfoot{}
|
||||
\ofoot*{\pagemark}
|
||||
\ifoot{}
|
||||
\setkomafont{pagehead}{\color{nexttokenslate}\sffamily\fontsize{8.5}{10}\selectfont}
|
||||
\setkomafont{pagenumber}{\color{nexttokenblue}\sffamily\bfseries\fontsize{9}{11}\selectfont}
|
||||
\KOMAoptions{headsepline=.4pt}
|
||||
\addtokomafont{headsepline}{\color{nexttokengold}}
|
||||
% Leerseiten (Verso nach Titel o.ä.) ohne Kolumnentitel/Seitenzahl
|
||||
\KOMAoptions{cleardoublepage=empty}
|
||||
|
||||
% ===========================================================================
|
||||
% 4) TOC
|
||||
% ===========================================================================
|
||||
\setcounter{tocdepth}{1}
|
||||
\AtBeginDocument{\hypersetup{bookmarksdepth=2}}
|
||||
\setcounter{secnumdepth}{-\maxdimen}
|
||||
\setkomafont{chapterentry}{\color{nexttokenblue}\sffamily}
|
||||
\KOMAoptions{toc=chapterentrywithdots}
|
||||
\DeclareTOCStyleEntry[
|
||||
beforeskip=.08em plus .1pt,
|
||||
entryformat=\small,
|
||||
pagenumberformat=\small
|
||||
]{tocline}{section}
|
||||
\DeclareTOCStyleEntry[beforeskip=.4em plus .1pt]{tocline}{chapter}
|
||||
|
||||
% ===========================================================================
|
||||
% 5) Code / Shaded — 9 pt, Zeilenumbruch im Satzspiegel
|
||||
% ===========================================================================
|
||||
\usepackage{framed}
|
||||
\usepackage{color}
|
||||
\definecolor{shadecolor}{gray}{0.96}
|
||||
|
||||
\usepackage{fvextra}
|
||||
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{
|
||||
breaklines=true,
|
||||
breakanywhere=true,
|
||||
commandchars=\\\{\},
|
||||
fontsize=\fontsize{9}{11}\selectfont
|
||||
}
|
||||
|
||||
% Inline-Code ~9 pt (Breaks in Tabellen: tables.lua; Body: emergencystretch)
|
||||
\let\oldtexttt\texttt
|
||||
\renewcommand{\texttt}[1]{{\fontsize{9}{11}\selectfont\oldtexttt{#1}}}
|
||||
|
||||
% ===========================================================================
|
||||
% 6) Zitat- / Hinweis-Boxen (Callouts: Kern / Übung / Achtung) — B/W
|
||||
% ===========================================================================
|
||||
\usepackage{mdframed}
|
||||
\usepackage{tikz}
|
||||
\usepackage{tcolorbox}
|
||||
\tcbuselibrary{breakable,skins}
|
||||
|
||||
\newmdenv[
|
||||
leftline=true,
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
linewidth=2.5pt,
|
||||
linecolor=nexttokengold,
|
||||
backgroundcolor=nexttokenparchment,
|
||||
leftmargin=0pt,
|
||||
rightmargin=0pt,
|
||||
innerleftmargin=10pt,
|
||||
innerrightmargin=6pt,
|
||||
innertopmargin=5pt,
|
||||
innerbottommargin=5pt,
|
||||
skipabove=10pt,
|
||||
skipbelow=10pt
|
||||
]{guidequotebox}
|
||||
|
||||
\newenvironment{guidequote}
|
||||
{\begin{guidequotebox}\itshape\color{nexttokenslate}}
|
||||
{\end{guidequotebox}}
|
||||
|
||||
\renewenvironment{quote}{%
|
||||
\begin{guidequotebox}\itshape\color{nexttokenslate}%
|
||||
}{%
|
||||
\end{guidequotebox}%
|
||||
}
|
||||
|
||||
\newcommand{\guideIconKern}{%
|
||||
\tikz[baseline=-0.28ex]{%
|
||||
\draw[line width=0.65pt, color=nexttokengold]
|
||||
(0,0) circle (0.30em);%
|
||||
\fill[nexttokengold] (0,0) circle (0.07em);%
|
||||
\draw[line width=0.65pt, color=nexttokengold]
|
||||
(0.10em,0.10em) -- (0.22em,0.22em);%
|
||||
}%
|
||||
}
|
||||
\newcommand{\guideIconUebung}{%
|
||||
\tikz[baseline=-0.28ex]{%
|
||||
\draw[line width=0.65pt, color=nexttokengold, rounded corners=0.4pt]
|
||||
(-0.02em,0) rectangle (0.50em,0.50em);%
|
||||
\draw[line width=0.75pt, color=nexttokengold, line cap=round, line join=round]
|
||||
(0.08em,0.24em) -- (0.20em,0.10em) -- (0.42em,0.40em);%
|
||||
}%
|
||||
}
|
||||
\newcommand{\guideIconAchtung}{%
|
||||
\tikz[baseline=-0.32ex]{%
|
||||
\draw[line width=0.65pt, color=guidecoral, line join=round]
|
||||
(0.28em,0.56em) -- (0.54em,0.06em) -- (0.02em,0.06em) -- cycle;%
|
||||
\draw[line width=0.7pt, color=guidecoral, line cap=round]
|
||||
(0.28em,0.40em) -- (0.28em,0.20em);%
|
||||
\fill[guidecoral] (0.28em,0.12em) circle (0.035em);%
|
||||
}%
|
||||
}
|
||||
|
||||
\newcommand{\guideCalloutLabel}[3]{%
|
||||
\noindent{\sffamily\bfseries\fontsize{9}{11}\selectfont\color{#1}%
|
||||
#3\enspace\MakeUppercase{#2}}\par\vspace{0.35em}%
|
||||
}
|
||||
|
||||
\tcbset{
|
||||
guidecallout/.style={
|
||||
enhanced,
|
||||
frame hidden,
|
||||
boxrule=0pt,
|
||||
leftrule=0pt,
|
||||
rightrule=0pt,
|
||||
toprule=0pt,
|
||||
bottomrule=0pt,
|
||||
left=11pt,
|
||||
right=9pt,
|
||||
top=8pt,
|
||||
bottom=8pt,
|
||||
arc=0pt,
|
||||
outer arc=0pt,
|
||||
boxsep=2pt,
|
||||
before skip=12pt,
|
||||
after skip=12pt,
|
||||
breakable,
|
||||
fontupper=\fontsize{9}{12}\selectfont\color{nexttokentext}
|
||||
},
|
||||
guideboxtitle/.style={
|
||||
fonttitle=\sffamily\bfseries\fontsize{8}{10}\selectfont,
|
||||
coltitle=nexttokenblue,
|
||||
attach boxed title to top left={yshift=-2pt, xshift=6pt},
|
||||
boxed title style={
|
||||
enhanced,
|
||||
frame hidden,
|
||||
colback=white,
|
||||
boxrule=0pt,
|
||||
left=2pt,
|
||||
right=2pt,
|
||||
top=0pt,
|
||||
bottom=0pt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% These/Kern — Teal-Grau, dicke Leiste
|
||||
\newtcolorbox{guidekern}{
|
||||
guidecallout,
|
||||
colback=nexttokenparchment,
|
||||
borderline west={3.2pt}{0pt}{nexttokengold}
|
||||
}
|
||||
|
||||
\newtcolorbox{guideuebung}{
|
||||
guidecallout,
|
||||
colback=nexttokenparchment,
|
||||
borderline west={2.8pt}{0pt}{nexttokengold}
|
||||
}
|
||||
|
||||
% Achtung — Coral-Grau
|
||||
\newtcolorbox{guideachtung}{
|
||||
guidecallout,
|
||||
colback=gray!10!white,
|
||||
borderline west={3.2pt}{0pt}{guidecoral}
|
||||
}
|
||||
|
||||
% Key Takeaways / Nächste Schritte (Filter takeaways.lua)
|
||||
\newtcolorbox{guidetakeaways}{
|
||||
guidecallout,
|
||||
guideboxtitle,
|
||||
colback=guidetakeawaysbg,
|
||||
borderline west={2.4pt}{0pt}{guidetakeaways},
|
||||
title={\color{guidetakeaways}KEY TAKEAWAYS}
|
||||
}
|
||||
|
||||
\newtcolorbox{guidenext}{
|
||||
guidecallout,
|
||||
guideboxtitle,
|
||||
colback=guidenextbg,
|
||||
borderline west={2.4pt}{0pt}{guidenextaccent},
|
||||
title={\color{guidenextaccent}PRAKTISCHE NÄCHSTE SCHRITTE}
|
||||
}
|
||||
|
||||
% ===========================================================================
|
||||
% 7) Tabellen — 9 pt, etwas luftiger
|
||||
% ===========================================================================
|
||||
\usepackage{array}
|
||||
\setlength{\tabcolsep}{4.2pt}
|
||||
\renewcommand{\arraystretch}{1.2}
|
||||
\setlength{\LTleft}{0pt}
|
||||
\setlength{\LTright}{0pt}
|
||||
|
||||
% ===========================================================================
|
||||
% 7b) Figures / Floats — mehr Weißraum
|
||||
% ===========================================================================
|
||||
\usepackage{float}
|
||||
\usepackage{placeins}
|
||||
\usepackage{etoolbox}
|
||||
\floatplacement{figure}{H}
|
||||
\BeforeBeginEnvironment{Shaded}{\FloatBarrier}
|
||||
\BeforeBeginEnvironment{verbatim}{\FloatBarrier}
|
||||
\BeforeBeginEnvironment{longtable}{\fontsize{9}{11}\selectfont}
|
||||
\BeforeBeginEnvironment{tabular}{\fontsize{9}{11}\selectfont}
|
||||
\setlength{\textfloatsep}{12pt plus 3pt minus 2pt}
|
||||
\setlength{\floatsep}{10pt plus 2pt minus 2pt}
|
||||
\setlength{\intextsep}{10pt plus 2pt minus 2pt}
|
||||
% Abbildungen: Textbreite ≈ 4,75 in · 0,87 · 300 ≈ 1239 px → 1280-Quellen ok
|
||||
\setkeys{Gin}{width=0.87\linewidth,keepaspectratio}
|
||||
|
||||
% ===========================================================================
|
||||
% 8) Titelseite — Cover-Abbildung (Grayscale), Fallback typografisch
|
||||
% KDP-Außenumschlag bleibt separat; Interior-Titelseite = Seite 1 mit Cover.
|
||||
% Ohne Bleed: Cover im Safe-Frame; KDP-Außenrand ≥ 0,25" → hier 0,30".
|
||||
% ===========================================================================
|
||||
\newcommand{\GuideTitlePageTypography}{%
|
||||
\centering
|
||||
\vspace*{2.2cm}%
|
||||
{\sffamily\color{nexttokengold}\large\bfseries\MakeUppercase{Praxisbuch}\par}%
|
||||
\vspace{0.9cm}%
|
||||
\rule{0.55\textwidth}{1.0pt}\par
|
||||
\vspace{1.0cm}%
|
||||
{\sffamily\color{nexttokenblue}\Huge\bfseries Coding Agents\par
|
||||
\vspace{0.3cm} in der Praxis\par}%
|
||||
\vspace{0.8cm}%
|
||||
\rule{0.55\textwidth}{1.0pt}\par
|
||||
\vspace{1.1cm}%
|
||||
{\sffamily\color{nexttokenslate}\large
|
||||
Ein pragmatischer Leitfaden zum effektiven Einsatz\par
|
||||
\vspace{0.3cm}
|
||||
von LLM-basierten Coding-Agents\par
|
||||
\vspace{0.3cm}
|
||||
unter Berücksichtigung ihrer Limitationen\par}%
|
||||
\vspace{1.8cm}%
|
||||
{\sffamily\color{nexttokentext}\large Martin Richardt\par}%
|
||||
\vspace{0.45cm}%
|
||||
{\sffamily\color{nexttokenslate}August 2026 · tool-agnostisch\par}%
|
||||
\vfill
|
||||
{\sffamily\color{nexttokenslate}\footnotesize
|
||||
Paperback-Interior · 6$\times$9 in · Grayscale\par}%
|
||||
}
|
||||
|
||||
\newcommand{\GuideTitlePageCover}[1]{%
|
||||
% Kein \null+\textheight: schmale Cover (Seitenverhältnis > 6×9) füllen sonst
|
||||
% die volle Höhe; \par/\null erzwingen dann eine leere Vorseite.
|
||||
\centering
|
||||
\vspace*{\fill}%
|
||||
\includegraphics[width=\textwidth,height=0.94\textheight,keepaspectratio]{#1}\par
|
||||
\vspace*{\fill}%
|
||||
}
|
||||
|
||||
\newcommand{\GuideTitlePage}{%
|
||||
% Ohne titlepage-Env (twoside erzeugt sonst Leer-Verso mit Header-Artefakten).
|
||||
% Safe-Frame 0,30" via newgeometry; danach restore + normaler Satzspiegel.
|
||||
% Kein führendes \clearpage: \newgeometry clearpage't bereits; sonst leere S.1.
|
||||
\thispagestyle{empty}%
|
||||
\pagestyle{empty}%
|
||||
\newgeometry{margin=0.30in}%
|
||||
\thispagestyle{empty}%
|
||||
% 1) Print-Assets (Grayscale) 2) Original 3) Typografie-Fallback
|
||||
\IfFileExists{build/print-assets/assets/cover/cover-front.jpg}{%
|
||||
\GuideTitlePageCover{build/print-assets/assets/cover/cover-front.jpg}%
|
||||
}{%
|
||||
\IfFileExists{assets/cover/cover-front.jpg}{%
|
||||
\GuideTitlePageCover{assets/cover/cover-front.jpg}%
|
||||
}{%
|
||||
\GuideTitlePageTypography
|
||||
}%
|
||||
}%
|
||||
\thispagestyle{empty}%
|
||||
% Ein \clearpage beendet die Titelseite; \restoregeometry clearpage't intern
|
||||
% → ein leeres Verso (Paperback üblich). Impressum-führendes \clearpage
|
||||
% landet danach direkt auf dem Impressum (kein zweites Leerblatt).
|
||||
\clearpage
|
||||
\restoregeometry
|
||||
\thispagestyle{empty}%
|
||||
\pagestyle{scrheadings}%
|
||||
}
|
||||
|
||||
% Fließtext-Farbe
|
||||
\AtBeginDocument{\color{nexttokentext}}
|
||||
@@ -0,0 +1,33 @@
|
||||
% guide-colors.tex — Premium-Outfit-Palette (eBook)
|
||||
% Geladen via Pandoc `-H`. Vorausgesetzt: xcolor (Template lädt es).
|
||||
% Zwei bunte Akzente: Teal (Struktur) + Coral (Risiko). Rest kalt/neutral.
|
||||
|
||||
\IfFileExists{xcolor.sty}{\usepackage{xcolor}}{}
|
||||
|
||||
% --- Hauptpalette -----------------------------------------------------------
|
||||
\definecolor{nexttokenblue}{HTML}{1A365D} % Indigo-Navy (H1, Kopf, TOC)
|
||||
\definecolor{nexttokengold}{HTML}{2A9D8F} % Teal (Primärakzent, Linien, These)
|
||||
\definecolor{nexttokenburgundy}{HTML}{9B2C2C} % Legacy-Rot (Fallback; nicht H2)
|
||||
\definecolor{nexttokentext}{HTML}{2C2C2C} % Anthrazit (Fließtext)
|
||||
\definecolor{nexttokenslate}{HTML}{4A5568} % Schiefer (Zitate, Hinweise)
|
||||
\definecolor{nexttokenparchment}{HTML}{F4F7F6} % Kühles Pergament
|
||||
\definecolor{nexttokenlink}{HTML}{1A365D}
|
||||
|
||||
% --- Semantik-Tokens (Premium-Welle) ----------------------------------------
|
||||
\definecolor{guidecoral}{HTML}{E07A5F} % Avoid / Achtung
|
||||
\definecolor{guidedo}{HTML}{2D6A4F} % Do-this-Text/Akzent
|
||||
\definecolor{guidetakeaways}{HTML}{475569} % Key-Takeaways (blau-grau)
|
||||
\definecolor{guidenextaccent}{HTML}{0F766E} % Praktische nächste Schritte
|
||||
\definecolor{nexttokensubsection}{HTML}{334155}% H3 — ruhiges Slate
|
||||
|
||||
\colorlet{nexttokenblue!soft}{nexttokenblue!18!white}
|
||||
\colorlet{nexttokengold!soft}{nexttokengold!25!white}
|
||||
\colorlet{nexttokenburgundy!soft}{nexttokenburgundy!12!white}
|
||||
\colorlet{guidecoral!soft}{guidecoral!12!white}
|
||||
|
||||
% Tabellen-Header / Do-Avoid (colortbl; eBook)
|
||||
\definecolor{guidetablehead}{HTML}{E8EEF5} % navy-tint Header
|
||||
\definecolor{guidedohead}{HTML}{E8F5EF} % kühles Grün „Do this“
|
||||
\definecolor{guideavoidhead}{HTML}{FCEEE9} % Coral-tint „Avoid that“
|
||||
\definecolor{guidetakeawaysbg}{HTML}{F1F5F9} % Key-Takeaways-Fond
|
||||
\definecolor{guidenextbg}{HTML}{F0FDFA} % Nächste-Schritte-Fond
|
||||
@@ -0,0 +1,329 @@
|
||||
% guide-preamble.tex — Präambel für Coding Agents in der Praxis (eBook A4)
|
||||
% Outfit + Premium: IBM Plex Serif body, Teal/Coral-Semantik, luftiger Rhythmus.
|
||||
% Farbtokens: guide-colors.tex
|
||||
|
||||
% ===========================================================================
|
||||
% 0) SPRACHE / SILBENTRENNUNG
|
||||
% ===========================================================================
|
||||
% Custom Pandoc-Template lädt babel nicht automatisch (trotz lang=de-DE).
|
||||
% shorthands=off: kein Konflikt mit csquotes \MakeOuterQuote{"} im Template
|
||||
\usepackage[shorthands=off,main=ngerman]{babel}
|
||||
|
||||
% ===========================================================================
|
||||
% 1) FONTS — IBM Plex (Fallback-Kette: DejaVu via luaotfload)
|
||||
% ===========================================================================
|
||||
% TeX Live: opentype/ibm/plex. Ohne Plex: Host braucht Charter/DejaVu-Fallback.
|
||||
\directlua{
|
||||
luaotfload.add_fallback("guidefb", {
|
||||
"DejaVu Serif:mode=node;",
|
||||
"DejaVu Sans:mode=node;",
|
||||
"DejaVu Sans Mono:mode=node;"
|
||||
})
|
||||
}
|
||||
\setmainfont{IBM Plex Serif}[
|
||||
Ligatures=TeX,
|
||||
Scale=MatchLowercase,
|
||||
RawFeature={fallback=guidefb}
|
||||
]
|
||||
\setsansfont{IBM Plex Sans}[
|
||||
Ligatures=TeX,
|
||||
Scale=MatchLowercase,
|
||||
RawFeature={fallback=guidefb}
|
||||
]
|
||||
\setmonofont{IBM Plex Mono}[
|
||||
Scale=MatchLowercase,
|
||||
RawFeature={fallback=guidefb}
|
||||
]
|
||||
|
||||
% Fließtext-Farbe
|
||||
\AtBeginDocument{\color{nexttokentext}}
|
||||
|
||||
% ===========================================================================
|
||||
% 2) KOMA-Script Überschriften — luftigere Kapitelanfänge
|
||||
% ===========================================================================
|
||||
\addtokomafont{chapter}{\color{nexttokenblue}\sffamily\bfseries\Huge}
|
||||
\addtokomafont{section}{\color{nexttokenblue}\sffamily\bfseries\Large}
|
||||
\addtokomafont{subsection}{\color{nexttokensubsection}\sffamily\bfseries\large}
|
||||
\addtokomafont{disposition}{\normalcolor}
|
||||
|
||||
% Chapter: mehr Weißraum; Section/Subsection großzügiger (Premium-Rhythmus)
|
||||
\RedeclareSectionCommand[
|
||||
beforeskip=2.5\baselineskip,
|
||||
afterskip=1.2\baselineskip
|
||||
]{chapter}
|
||||
\RedeclareSectionCommand[
|
||||
beforeskip=1.7\baselineskip,
|
||||
afterskip=0.65\baselineskip
|
||||
]{section}
|
||||
\RedeclareSectionCommand[
|
||||
beforeskip=1.2\baselineskip,
|
||||
afterskip=0.45\baselineskip
|
||||
]{subsection}
|
||||
|
||||
% Dünne Gold-Linie unter Kapitel-Titel (unnumbered Manuskript-Kapitel)
|
||||
\renewcommand{\chapterlinesformat}[3]{%
|
||||
\raggedsection
|
||||
#3\par
|
||||
\nobreak\vspace{0.45em}%
|
||||
{\color{nexttokengold}\rule{0.28\textwidth}{1.6pt}}\par
|
||||
\nobreak\vspace{0.55em}%
|
||||
}
|
||||
|
||||
% ===========================================================================
|
||||
% 3) Kopf-/Fußzeile
|
||||
% ===========================================================================
|
||||
\usepackage{scrlayer-scrpage}
|
||||
\clearpairofpagestyles
|
||||
\lehead{\headmark}
|
||||
\rohead{\headmark}
|
||||
\chead{}
|
||||
\cfoot*{\pagemark}
|
||||
\setkomafont{pagehead}{\color{nexttokenblue}\sffamily\small}
|
||||
\setkomafont{pagenumber}{\color{nexttokengold}\sffamily\bfseries}
|
||||
\KOMAoptions{headsepline=.6pt}
|
||||
\addtokomafont{headsepline}{\color{nexttokengold}}
|
||||
|
||||
% ===========================================================================
|
||||
% 4) TOC
|
||||
% ===========================================================================
|
||||
% 1 = Kapitel + kuratierte Abschnitte (##); Satellite-## via Pandoc {.unlisted}
|
||||
\setcounter{tocdepth}{1}
|
||||
\AtBeginDocument{\hypersetup{bookmarksdepth=2}}
|
||||
% Manuskript trägt eigene Nummern — keine Auto-Zählung
|
||||
\setcounter{secnumdepth}{-\maxdimen}
|
||||
\setkomafont{chapterentry}{\color{nexttokenblue}\sffamily}
|
||||
\KOMAoptions{toc=chapterentrywithdots}
|
||||
\DeclareTOCStyleEntry[
|
||||
beforeskip=.12em plus .1pt,
|
||||
entryformat=\small,
|
||||
pagenumberformat=\small
|
||||
]{tocline}{section}
|
||||
\DeclareTOCStyleEntry[beforeskip=.55em plus .1pt]{tocline}{chapter}
|
||||
|
||||
% ===========================================================================
|
||||
% 5) Code / Shaded
|
||||
% ===========================================================================
|
||||
\usepackage{framed}
|
||||
\usepackage{color}
|
||||
% Code-Fond: etwas dunkler als reines Weiß → klarere Mono-Unterscheidung
|
||||
\definecolor{shadecolor}{RGB}{240,242,245}
|
||||
|
||||
% Lange Codezeilen umbrechen statt über den Rand
|
||||
\usepackage{fvextra}
|
||||
\DefineVerbatimEnvironment{Highlighting}{Verbatim}{
|
||||
breaklines=true,
|
||||
breakanywhere=true,
|
||||
commandchars=\\\{\},
|
||||
fontsize=\small
|
||||
}
|
||||
|
||||
% ===========================================================================
|
||||
% 6) Zitat- / Hinweis-Boxen (Callouts + Takeaways)
|
||||
% ===========================================================================
|
||||
\usepackage{mdframed}
|
||||
\usepackage{tikz}
|
||||
\usepackage{tcolorbox}
|
||||
\tcbuselibrary{breakable,skins}
|
||||
|
||||
\newmdenv[
|
||||
leftline=true,
|
||||
rightline=false,
|
||||
topline=false,
|
||||
bottomline=false,
|
||||
linewidth=2.5pt,
|
||||
linecolor=nexttokengold,
|
||||
backgroundcolor=nexttokenslate!5!white,
|
||||
leftmargin=0pt,
|
||||
rightmargin=0pt,
|
||||
innerleftmargin=12pt,
|
||||
innerrightmargin=9pt,
|
||||
innertopmargin=7pt,
|
||||
innerbottommargin=7pt,
|
||||
skipabove=14pt,
|
||||
skipbelow=14pt
|
||||
]{guidequotebox}
|
||||
|
||||
\newenvironment{guidequote}
|
||||
{\begin{guidequotebox}\itshape\color{nexttokenslate}}
|
||||
{\end{guidequotebox}}
|
||||
|
||||
% Unklassifizierte Pandoc-Blockquotes (z. B. Prompt-Transkripte)
|
||||
\renewenvironment{quote}{%
|
||||
\begin{guidequotebox}\itshape\color{nexttokenslate}%
|
||||
}{%
|
||||
\end{guidequotebox}%
|
||||
}
|
||||
|
||||
% --- Monoline-Icons (drucktauglich; Farben = Semantik) ----------------------
|
||||
\newcommand{\guideIconKern}{%
|
||||
\tikz[baseline=-0.28ex]{%
|
||||
\draw[line width=0.65pt, color=nexttokengold]
|
||||
(0,0) circle (0.30em);%
|
||||
\fill[nexttokengold] (0,0) circle (0.07em);%
|
||||
\draw[line width=0.65pt, color=nexttokengold]
|
||||
(0.10em,0.10em) -- (0.22em,0.22em);%
|
||||
}%
|
||||
}
|
||||
\newcommand{\guideIconUebung}{%
|
||||
\tikz[baseline=-0.28ex]{%
|
||||
\draw[line width=0.65pt, color=nexttokengold, rounded corners=0.4pt]
|
||||
(-0.02em,0) rectangle (0.50em,0.50em);%
|
||||
\draw[line width=0.75pt, color=nexttokengold, line cap=round, line join=round]
|
||||
(0.08em,0.24em) -- (0.20em,0.10em) -- (0.42em,0.40em);%
|
||||
}%
|
||||
}
|
||||
\newcommand{\guideIconAchtung}{%
|
||||
\tikz[baseline=-0.32ex]{%
|
||||
\draw[line width=0.65pt, color=guidecoral, line join=round]
|
||||
(0.28em,0.56em) -- (0.54em,0.06em) -- (0.02em,0.06em) -- cycle;%
|
||||
\draw[line width=0.7pt, color=guidecoral, line cap=round]
|
||||
(0.28em,0.40em) -- (0.28em,0.20em);%
|
||||
\fill[guidecoral] (0.28em,0.12em) circle (0.035em);%
|
||||
}%
|
||||
}
|
||||
|
||||
% Labelzeile: Icon + Kapitälchen-artiger Sans-Label
|
||||
\newcommand{\guideCalloutLabel}[3]{%
|
||||
\noindent{\sffamily\bfseries\fontsize{8.2}{10}\selectfont\color{#1}%
|
||||
#3\enspace\MakeUppercase{#2}}\par\vspace{0.35em}%
|
||||
}
|
||||
|
||||
\tcbset{
|
||||
guidecallout/.style={
|
||||
enhanced,
|
||||
frame hidden,
|
||||
boxrule=0pt,
|
||||
leftrule=0pt,
|
||||
rightrule=0pt,
|
||||
toprule=0pt,
|
||||
bottomrule=0pt,
|
||||
left=11pt,
|
||||
right=9pt,
|
||||
top=8pt,
|
||||
bottom=8pt,
|
||||
arc=0pt,
|
||||
outer arc=0pt,
|
||||
boxsep=2pt,
|
||||
before skip=1.05em,
|
||||
after skip=1.05em,
|
||||
breakable,
|
||||
fontupper=\normalsize\color{nexttokentext}
|
||||
},
|
||||
guideboxtitle/.style={
|
||||
fonttitle=\sffamily\bfseries\fontsize{8}{10}\selectfont,
|
||||
coltitle=nexttokenblue,
|
||||
attach boxed title to top left={yshift=-2pt, xshift=6pt},
|
||||
boxed title style={
|
||||
enhanced,
|
||||
frame hidden,
|
||||
colback=white,
|
||||
boxrule=0pt,
|
||||
left=2pt,
|
||||
right=2pt,
|
||||
top=0pt,
|
||||
bottom=0pt
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
% Kern / These — Primärakzent Teal (dicke Leiste = „lesen“)
|
||||
\newtcolorbox{guidekern}{
|
||||
guidecallout,
|
||||
colback=nexttokengold!6!white,
|
||||
borderline west={3.5pt}{0pt}{nexttokengold}
|
||||
}
|
||||
|
||||
% Übung — Jetzt selbst machen (Teal, etwas dünner)
|
||||
\newtcolorbox{guideuebung}{
|
||||
guidecallout,
|
||||
colback=nexttokengold!8!white,
|
||||
borderline west={3.0pt}{0pt}{nexttokengold}
|
||||
}
|
||||
|
||||
% Achtung — Risiko / Security (Coral)
|
||||
\newtcolorbox{guideachtung}{
|
||||
guidecallout,
|
||||
colback=guidecoral!7!white,
|
||||
borderline west={3.5pt}{0pt}{guidecoral}
|
||||
}
|
||||
|
||||
% Key Takeaways — kühles Blau-Grau (dünnere Leiste = Abschluss)
|
||||
\newtcolorbox{guidetakeaways}{
|
||||
guidecallout,
|
||||
guideboxtitle,
|
||||
colback=guidetakeawaysbg,
|
||||
borderline west={2.5pt}{0pt}{guidetakeaways},
|
||||
title={\color{guidetakeaways}KEY TAKEAWAYS}
|
||||
}
|
||||
|
||||
% Praktische nächste Schritte — Grün-Teal
|
||||
\newtcolorbox{guidenext}{
|
||||
guidecallout,
|
||||
guideboxtitle,
|
||||
colback=guidenextbg,
|
||||
borderline west={2.5pt}{0pt}{guidenextaccent},
|
||||
title={\color{guidenextaccent}PRAKTISCHE NÄCHSTE SCHRITTE}
|
||||
}
|
||||
|
||||
% ===========================================================================
|
||||
% 7) Tabellen (longtable aus Pandoc-Pipe-Tables)
|
||||
% ===========================================================================
|
||||
% Breite/Schrift pro Tabelle: pdf/filters/tables.lua
|
||||
% Header-Farben: colortbl + tables.lua (\rowcolor)
|
||||
\usepackage{array}
|
||||
\setlength{\tabcolsep}{5.5pt}
|
||||
\renewcommand{\arraystretch}{1.22}
|
||||
\setlength{\LTleft}{0pt}
|
||||
\setlength{\LTright}{0pt}
|
||||
|
||||
% ===========================================================================
|
||||
% 7b) Figures / Floats — fest am Markdown-Anker (kein Drift in Listings)
|
||||
% ===========================================================================
|
||||
\usepackage{float}
|
||||
\usepackage{placeins}
|
||||
\usepackage{etoolbox}
|
||||
\floatplacement{figure}{H}
|
||||
\BeforeBeginEnvironment{Shaded}{\FloatBarrier}
|
||||
\BeforeBeginEnvironment{verbatim}{\FloatBarrier}
|
||||
\setlength{\textfloatsep}{16pt plus 3pt minus 2pt}
|
||||
\setlength{\floatsep}{14pt plus 2pt minus 2pt}
|
||||
\setlength{\intextsep}{14pt plus 2pt minus 2pt}
|
||||
|
||||
% Listen luftiger (Premium-Rhythmus)
|
||||
\setlist{itemsep=0.28em, topsep=0.45em, parsep=0.15em}
|
||||
|
||||
% ===========================================================================
|
||||
% 8) Titelseite
|
||||
% ===========================================================================
|
||||
\newcommand{\GuideTitlePage}{%
|
||||
\begin{titlepage}%
|
||||
\thispagestyle{empty}%
|
||||
\centering
|
||||
\IfFileExists{assets/cover/cover-front.jpg}{%
|
||||
\vspace*{0.4cm}%
|
||||
\includegraphics[height=0.88\textheight,keepaspectratio]{assets/cover/cover-front.jpg}\par
|
||||
}{%
|
||||
\vspace*{2.0cm}%
|
||||
{\sffamily\color{nexttokengold}\large\bfseries\MakeUppercase{Praxisbuch}\par}%
|
||||
\vspace{0.8cm}%
|
||||
\rule{0.50\textwidth}{1.2pt}\par
|
||||
\vspace{0.9cm}%
|
||||
{\sffamily\color{nexttokenblue}\Huge\bfseries Coding Agents\par
|
||||
\vspace{0.25cm} in der Praxis\par}%
|
||||
\vspace{0.7cm}%
|
||||
\rule{0.50\textwidth}{1.2pt}\par
|
||||
\vspace{1.0cm}%
|
||||
{\sffamily\color{nexttokenslate}\large
|
||||
Ein pragmatischer Leitfaden zum effektiven Einsatz\par
|
||||
\vspace{0.25cm}
|
||||
von LLM-basierten Coding-Agents\par
|
||||
\vspace{0.25cm}
|
||||
unter Berücksichtigung ihrer Limitationen\par}%
|
||||
\vspace{1.6cm}%
|
||||
{\sffamily\color{nexttokentext}\large Martin Richardt\par}%
|
||||
\vspace{0.4cm}%
|
||||
{\sffamily\color{nexttokenslate}August 2026 · tool-agnostisch\par}%
|
||||
\vfill
|
||||
}%
|
||||
\end{titlepage}%
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
\documentclass[
|
||||
$if(fontsize)$
|
||||
$fontsize$,
|
||||
$else$
|
||||
11pt,
|
||||
$endif$
|
||||
$if(geometry)$
|
||||
$elseif(papersize)$
|
||||
$papersize$paper,
|
||||
$else$
|
||||
a4paper,
|
||||
$endif$
|
||||
$if(print-interior)$
|
||||
twoside,
|
||||
openany,
|
||||
BCOR=0mm,
|
||||
$else$
|
||||
oneside,
|
||||
openany,
|
||||
DIV=13,
|
||||
BCOR=0mm,
|
||||
$endif$
|
||||
$for(classoption)$
|
||||
$classoption$$sep$,
|
||||
$endfor$
|
||||
]{scrbook}
|
||||
|
||||
\usepackage{xcolor}
|
||||
\definecolor{nexttokenlink}{HTML}{1A365D}
|
||||
|
||||
$if(geometry)$
|
||||
\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry}
|
||||
$endif$
|
||||
|
||||
\usepackage{amsmath,amssymb}
|
||||
|
||||
$if(numbersections)$
|
||||
\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$-1$endif$}
|
||||
$else$
|
||||
\setcounter{secnumdepth}{-\maxdimen}
|
||||
$endif$
|
||||
|
||||
\usepackage{iftex}
|
||||
\ifLuaTeX
|
||||
\usepackage{fontspec}
|
||||
\setmainfont{Latin Modern Roman}
|
||||
\setsansfont{Latin Modern Sans}
|
||||
\setmonofont{Latin Modern Mono}
|
||||
\else
|
||||
\usepackage{lmodern}
|
||||
\fi
|
||||
\usepackage{setspace}
|
||||
|
||||
\usepackage[autostyle=true,german=quotes]{csquotes}
|
||||
\MakeOuterQuote{"}
|
||||
|
||||
% microtype (LuaLaTeX): Protrusion + Expansion; spacing/kerning sind pdfTeX-only
|
||||
\IfFileExists{microtype.sty}{%
|
||||
\usepackage[
|
||||
protrusion=true,
|
||||
expansion=true,
|
||||
tracking=false,
|
||||
kerning=false,
|
||||
spacing=false,
|
||||
factor=1100,
|
||||
stretch=20,
|
||||
shrink=20
|
||||
]{microtype}%
|
||||
\UseMicrotypeSet[protrusion]{basicmath}%
|
||||
}{}
|
||||
|
||||
\usepackage{booktabs}
|
||||
\usepackage{colortbl}
|
||||
\usepackage{calc}
|
||||
\usepackage{enumitem}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{longtable,array}
|
||||
|
||||
\providecommand{\tightlist}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
|
||||
|
||||
$for(header-includes)$
|
||||
$header-includes$
|
||||
$endfor$
|
||||
|
||||
$highlighting-macros$
|
||||
|
||||
$if(print-interior)$
|
||||
\IfFileExists{pdf/print/print-preamble.tex}{%
|
||||
\input{pdf/print/print-preamble.tex}%
|
||||
}{%
|
||||
\InputIfFileExists{print-preamble.tex}{}{}%
|
||||
}
|
||||
$else$
|
||||
\IfFileExists{pdf/templates/guide-preamble.tex}{%
|
||||
\input{pdf/templates/guide-preamble.tex}%
|
||||
}{%
|
||||
\InputIfFileExists{guide-preamble.tex}{}{}%
|
||||
}
|
||||
$endif$
|
||||
|
||||
\usepackage{hyperref}
|
||||
\hypersetup{
|
||||
$if(title-meta)$
|
||||
pdftitle={$title-meta$},
|
||||
$endif$
|
||||
$if(author-meta)$
|
||||
pdfauthor={$author-meta$},
|
||||
$endif$
|
||||
pdflang={de},
|
||||
$if(colorlinks)$
|
||||
colorlinks=true,
|
||||
linkcolor=$if(linkcolor)$$linkcolor$$else$nexttokenlink$endif$,
|
||||
urlcolor=$if(urlcolor)$$urlcolor$$else$nexttokenlink$endif$,
|
||||
citecolor=$if(citecolor)$$citecolor$$else$nexttokenlink$endif$
|
||||
$else$
|
||||
hidelinks
|
||||
$endif$
|
||||
}
|
||||
|
||||
$if(title)$
|
||||
\title{$title$$if(thanks)$\thanks{$thanks$}$endif$}
|
||||
$endif$
|
||||
$if(subtitle)$
|
||||
\usepackage{etoolbox}
|
||||
\makeatletter
|
||||
\providecommand{\subtitle}[1]{%
|
||||
\apptocmd{\@title}{\par {\large #1 \par}}{}{}
|
||||
}
|
||||
\makeatother
|
||||
\subtitle{$subtitle$}
|
||||
$endif$
|
||||
\author{$for(author)$$author$$sep$ \and $endfor$}
|
||||
\date{$date$}
|
||||
|
||||
\begin{document}
|
||||
|
||||
\GuideTitlePage
|
||||
|
||||
$if(has-frontmatter)$
|
||||
\frontmatter
|
||||
$endif$
|
||||
|
||||
\IfFileExists{pdf/front/impressum.tex}{%
|
||||
\input{pdf/front/impressum.tex}%
|
||||
}{}
|
||||
|
||||
$for(include-before)$
|
||||
$include-before$
|
||||
|
||||
$endfor$
|
||||
|
||||
$if(toc)$
|
||||
$if(toc-title)$
|
||||
\renewcommand*\contentsname{$toc-title$}
|
||||
$endif$
|
||||
{
|
||||
$if(colorlinks)$
|
||||
\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$nexttokenlink$endif$}
|
||||
$endif$
|
||||
\setcounter{tocdepth}{$if(toc-depth)$$toc-depth$$else$1$endif$}
|
||||
\tableofcontents
|
||||
}
|
||||
$endif$
|
||||
|
||||
$if(linestretch)$
|
||||
\setstretch{$linestretch$}
|
||||
$endif$
|
||||
|
||||
$if(has-frontmatter)$
|
||||
\mainmatter
|
||||
$endif$
|
||||
|
||||
$body$
|
||||
|
||||
$if(has-frontmatter)$
|
||||
\backmatter
|
||||
$endif$
|
||||
|
||||
% Über den Autor (mit TOC-Eintrag)
|
||||
\IfFileExists{pdf/back/ueber-den-autor.tex}{%
|
||||
\input{pdf/back/ueber-den-autor.tex}%
|
||||
}{}
|
||||
|
||||
$for(include-after)$
|
||||
$include-after$
|
||||
|
||||
$endfor$
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,3 @@
|
||||
# reviews/
|
||||
|
||||
Prüfprotokolle aus `total-check` (`vollpruefung-YYYY-MM-DD.md`). Nicht im PDF, kein Default-Load.
|
||||
@@ -0,0 +1,607 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Assemble Coding-Agents-in-der-Praxis chapters for the PDF pipeline.
|
||||
|
||||
Concatenates root chapter files ``01-*.md`` … ``22-*.md`` (plus Anhänge A/B)
|
||||
into ``build/book.md``. Strips per-chapter markdown-only noise that would
|
||||
duplicate PDF frontmatter. Heading levels stay as written (``#`` =
|
||||
chapter, ``##`` = section) for KOMA ``scrbook``.
|
||||
|
||||
Also types blockquotes and exercise markers into LaTeX callout boxes
|
||||
(``guidekern``, ``guideuebung``, ``guideachtung``) defined in
|
||||
``pdf/templates/guide-preamble.tex``.
|
||||
|
||||
CLI:
|
||||
python3 scripts/assemble_book.py [--out PATH]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||
BUILD_DIR = REPO_ROOT / "build"
|
||||
DEFAULT_TARGET = BUILD_DIR / "book.md"
|
||||
|
||||
def _chapter_order() -> list[str]:
|
||||
"""Kapitel dynamisch aus dem Repo-Root: NN-*.md (ohne 00-TOC)."""
|
||||
return sorted(
|
||||
p.name
|
||||
for p in REPO_ROOT.glob("[0-9][0-9]-*.md")
|
||||
if p.name != "00-inhaltsverzeichnis.md"
|
||||
)
|
||||
|
||||
|
||||
CHAPTER_ORDER = _chapter_order()
|
||||
|
||||
# Drop markdown-only TOC blocks if present.
|
||||
_TOC_RE = re.compile(
|
||||
r"^##\s+Inhaltsverzeichnis\s*\n"
|
||||
r".*?"
|
||||
r"(?=^---\s*$|^##\s+|^#\s+)",
|
||||
re.MULTILINE | re.DOTALL,
|
||||
)
|
||||
|
||||
# Soften raw HTML comments (except callout markers — handled earlier).
|
||||
_HTML_COMMENT_RE = re.compile(r"<!--.*?-->", re.DOTALL)
|
||||
|
||||
# List items ending with two+ trailing spaces become LaTeX ``\\`` after each
|
||||
# ``\item``. Even with ``\tightlist`` that doubles visual row spacing in the PDF.
|
||||
# Only horizontal spaces (not ``\s``) so the blank line after a list stays intact.
|
||||
_LIST_ITEM_HARDBREAK_RE = re.compile(
|
||||
r"^(\s*(?:[-*+]|\d+\.)\s+\S.*?)[^\S\n]{2,}$",
|
||||
re.MULTILINE,
|
||||
)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Callout typing (Kern / Übung / Achtung)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
_LABEL_PREFIX = re.compile(
|
||||
r"^\*\*(?P<label>[^*]+?):\*\*(?P<rest>\s*.*)$",
|
||||
)
|
||||
|
||||
# Blockquote first-line labels → (env, color, display_label)
|
||||
# display_label is used as shown; for These N we prefer the matched raw label.
|
||||
_BQ_LABEL_RULES: list[tuple[re.Pattern[str], str, str, str | None]] = [
|
||||
(
|
||||
re.compile(r"^These\s+\d+$", re.IGNORECASE),
|
||||
"guidekern",
|
||||
"nexttokengold", # Teal — These/Kern-Akzent
|
||||
None, # use matched raw label (These N)
|
||||
),
|
||||
(
|
||||
re.compile(r"^These$", re.IGNORECASE),
|
||||
"guidekern",
|
||||
"nexttokengold",
|
||||
"These",
|
||||
),
|
||||
(
|
||||
re.compile(r"^Kern(?:\s+in\s+einem\s+Satz)?$", re.IGNORECASE),
|
||||
"guidekern",
|
||||
"nexttokengold",
|
||||
"Kern",
|
||||
),
|
||||
(
|
||||
re.compile(r"^Achtung$", re.IGNORECASE),
|
||||
"guideachtung",
|
||||
"guidecoral", # Coral — Risiko / Avoid-Semantik
|
||||
"Achtung",
|
||||
),
|
||||
]
|
||||
|
||||
_UEBUNG_HEADING = re.compile(
|
||||
r"^###\s+Jetzt\s+selbst\s+machen\s*:\s*(?P<title>.+?)\s*$",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
_UEBUNG_INLINE = re.compile(
|
||||
r"^\*\*Jetzt\s+selbst\s+machen:\*\*\s*(?P<body>.*)$"
|
||||
r"|^\*\*Jetzt\s+selbst\s+machen\*\*"
|
||||
r"(?:\s*\([^)]*\))?\s*:?\s*(?P<body2>.*)$",
|
||||
re.IGNORECASE,
|
||||
)
|
||||
|
||||
# Stop wrapping an inline exercise when this line starts a new thought/section.
|
||||
_UEBUNG_STOP = re.compile(
|
||||
r"^(?:"
|
||||
r"#{1,6}\s" # heading
|
||||
r"|---\s*$" # hr
|
||||
r"|\*\*(?:Warum|Wie|Was du|Gegen |Praktische |Gute |Schlechte |"
|
||||
r"Onboarding|Drei |Für |Der verlockende|Wann |Mini-|Advisor |"
|
||||
r"Kontext-Ventil|Start |Team-|Rein:|Raus:|Was du suchst)"
|
||||
r")",
|
||||
)
|
||||
|
||||
# For ###-style exercises: stop at next same-or-higher heading or ---
|
||||
_SECTION_STOP = re.compile(r"^(?:#{1,3}\s|---\s*$)")
|
||||
|
||||
|
||||
def escape_latex_plain(text: str) -> str:
|
||||
out: list[str] = []
|
||||
for ch in text:
|
||||
if ch == "\\":
|
||||
out.append(r"\textbackslash{}")
|
||||
elif ch == "{":
|
||||
out.append(r"\{")
|
||||
elif ch == "}":
|
||||
out.append(r"\}")
|
||||
elif ch == "$":
|
||||
out.append(r"\$")
|
||||
elif ch == "&":
|
||||
out.append(r"\&")
|
||||
elif ch == "%":
|
||||
out.append(r"\%")
|
||||
elif ch == "#":
|
||||
out.append(r"\#")
|
||||
elif ch == "_":
|
||||
out.append(r"\_")
|
||||
elif ch == "^":
|
||||
out.append(r"\textasciicircum{}")
|
||||
elif ch == "~":
|
||||
out.append(r"\textasciitilde{}")
|
||||
elif ch == "\u00a0":
|
||||
out.append("~")
|
||||
else:
|
||||
out.append(ch)
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def md_inline_to_latex(text: str) -> str:
|
||||
"""Convert a subset of MD inline markup to LaTeX (code, bold, italic)."""
|
||||
codes: list[str] = []
|
||||
|
||||
def stash_code(m: re.Match[str]) -> str:
|
||||
codes.append(m.group(1))
|
||||
return f"\x00C{len(codes) - 1}\x00"
|
||||
|
||||
s = re.sub(r"`([^`]+)`", stash_code, text)
|
||||
|
||||
bolds: list[str] = []
|
||||
|
||||
def stash_bold(m: re.Match[str]) -> str:
|
||||
bolds.append(m.group(1))
|
||||
return f"\x00B{len(bolds) - 1}\x00"
|
||||
|
||||
s = re.sub(r"\*\*(.+?)\*\*", stash_bold, s)
|
||||
|
||||
italics: list[str] = []
|
||||
|
||||
def stash_italic(m: re.Match[str]) -> str:
|
||||
italics.append(m.group(1))
|
||||
return f"\x00I{len(italics) - 1}\x00"
|
||||
|
||||
s = re.sub(r"(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)", stash_italic, s)
|
||||
s = escape_latex_plain(s)
|
||||
|
||||
def restore_italic(m: re.Match[str]) -> str:
|
||||
return r"\textit{" + escape_latex_plain(italics[int(m.group(1))]) + "}"
|
||||
|
||||
s = re.sub(r"\x00I(\d+)\x00", restore_italic, s)
|
||||
|
||||
def restore_bold(m: re.Match[str]) -> str:
|
||||
return r"\textbf{" + escape_latex_plain(bolds[int(m.group(1))]) + "}"
|
||||
|
||||
s = re.sub(r"\x00B(\d+)\x00", restore_bold, s)
|
||||
|
||||
def restore_code(m: re.Match[str]) -> str:
|
||||
return r"\texttt{" + escape_latex_plain(codes[int(m.group(1))]) + "}"
|
||||
|
||||
s = re.sub(r"\x00C(\d+)\x00", restore_code, s)
|
||||
return s
|
||||
|
||||
|
||||
def _icon_macro(env: str) -> str:
|
||||
if env == "guidekern":
|
||||
return r"\guideIconKern"
|
||||
if env == "guideuebung":
|
||||
return r"\guideIconUebung"
|
||||
if env == "guideachtung":
|
||||
return r"\guideIconAchtung"
|
||||
return ""
|
||||
|
||||
|
||||
def _label_line(env: str, color: str, label: str) -> str:
|
||||
icon = _icon_macro(env)
|
||||
return (
|
||||
f"\\guideCalloutLabel{{{color}}}{{{escape_latex_plain(label)}}}{{{icon}}}"
|
||||
)
|
||||
|
||||
|
||||
def _latex_raw_block(inner: str) -> str:
|
||||
return f"```{{=latex}}\n{inner}\n```\n"
|
||||
|
||||
|
||||
def blockquote_to_callout(content_lines: list[str]) -> str | None:
|
||||
"""Return raw-LaTeX fenced block for typed callout, or None to keep MD quote."""
|
||||
lines = list(content_lines)
|
||||
while lines and not lines[0].strip():
|
||||
lines = lines[1:]
|
||||
while lines and not lines[-1].strip():
|
||||
lines = lines[:-1]
|
||||
if not lines:
|
||||
return None
|
||||
|
||||
first = lines[0].strip()
|
||||
m = _LABEL_PREFIX.match(first)
|
||||
if not m:
|
||||
return None
|
||||
|
||||
raw_label = m.group("label").strip()
|
||||
rest = m.group("rest").lstrip()
|
||||
matched: tuple[str, str, str] | None = None
|
||||
for pat, env, color, display in _BQ_LABEL_RULES:
|
||||
if pat.match(raw_label):
|
||||
shown = display if display is not None else raw_label
|
||||
matched = (env, color, shown)
|
||||
break
|
||||
if matched is None:
|
||||
return None
|
||||
|
||||
env, color, display = matched
|
||||
body_parts: list[str] = []
|
||||
if rest:
|
||||
body_parts.append(rest)
|
||||
body_parts.extend(lines[1:])
|
||||
|
||||
latex_chunks: list[str] = []
|
||||
para: list[str] = []
|
||||
|
||||
def flush() -> None:
|
||||
nonlocal para
|
||||
if not para:
|
||||
return
|
||||
joined = " ".join(p.strip() for p in para if p.strip())
|
||||
if joined:
|
||||
latex_chunks.append(md_inline_to_latex(joined))
|
||||
para = []
|
||||
|
||||
for part in body_parts:
|
||||
if not part.strip():
|
||||
flush()
|
||||
continue
|
||||
para.append(part.strip())
|
||||
flush()
|
||||
|
||||
body = r"\par ".join(latex_chunks) if latex_chunks else ""
|
||||
parts = [f"\\begin{{{env}}}", _label_line(env, color, display)]
|
||||
if body:
|
||||
parts.append(body)
|
||||
parts.append(f"\\end{{{env}}}")
|
||||
return _latex_raw_block("\n".join(parts))
|
||||
|
||||
|
||||
def _strip_bq_prefix(line: str) -> str:
|
||||
if line.startswith("> "):
|
||||
return line[2:]
|
||||
if line.startswith(">"):
|
||||
return line[1:]
|
||||
return line
|
||||
|
||||
|
||||
def _is_callout_label_line(line: str) -> bool:
|
||||
"""True if line is a typed callout opener (**These N:**, **Kern:**, **Achtung:**)."""
|
||||
m = _LABEL_PREFIX.match(line.strip())
|
||||
if not m:
|
||||
return False
|
||||
raw = m.group("label").strip()
|
||||
return any(pat.match(raw) for pat, *_rest in _BQ_LABEL_RULES)
|
||||
|
||||
|
||||
def _split_labeled_callout_blocks(content_lines: list[str]) -> list[list[str]]:
|
||||
"""Split one MD blockquote into sub-blocks when a new callout label starts.
|
||||
|
||||
CommonMark (and this assembler) keep consecutive ``>`` lines as *one*
|
||||
blockquote even across blank lines. Without a split, ``These 2`` + ``These 3``
|
||||
in the same quote become a single box labeled only with the first These.
|
||||
"""
|
||||
blocks: list[list[str]] = []
|
||||
current: list[str] = []
|
||||
for line in content_lines:
|
||||
if _is_callout_label_line(line) and any(x.strip() for x in current):
|
||||
blocks.append(current)
|
||||
current = [line]
|
||||
else:
|
||||
current.append(line)
|
||||
if current:
|
||||
blocks.append(current)
|
||||
return blocks
|
||||
|
||||
|
||||
def transform_blockquotes(text: str) -> str:
|
||||
lines = text.splitlines(keepends=False)
|
||||
out: list[str] = []
|
||||
i = 0
|
||||
n = len(lines)
|
||||
|
||||
while i < n:
|
||||
if lines[i].startswith(">"):
|
||||
block: list[str] = []
|
||||
start = i
|
||||
while i < n:
|
||||
if lines[i].startswith(">"):
|
||||
block.append(_strip_bq_prefix(lines[i]))
|
||||
i += 1
|
||||
elif (
|
||||
lines[i].strip() == ""
|
||||
and i + 1 < n
|
||||
and lines[i + 1].startswith(">")
|
||||
):
|
||||
block.append("")
|
||||
i += 1
|
||||
else:
|
||||
break
|
||||
# One MD quote may hold several typed theses/kerns; emit one box each.
|
||||
subblocks = _split_labeled_callout_blocks(block)
|
||||
converted_parts: list[str] = []
|
||||
all_ok = True
|
||||
for sub in subblocks:
|
||||
if not any(x.strip() for x in sub):
|
||||
continue
|
||||
converted = blockquote_to_callout(sub)
|
||||
if converted is None:
|
||||
all_ok = False
|
||||
break
|
||||
converted_parts.append(converted.rstrip("\n"))
|
||||
if all_ok and converted_parts:
|
||||
out.append("\n\n".join(converted_parts))
|
||||
if i < n and lines[i].strip() == "":
|
||||
out.append("")
|
||||
i += 1
|
||||
else:
|
||||
# Keep original blockquote lines
|
||||
out.extend(lines[start:i])
|
||||
else:
|
||||
out.append(lines[i])
|
||||
i += 1
|
||||
|
||||
return "\n".join(out) + ("\n" if text.endswith("\n") else "")
|
||||
|
||||
|
||||
def _open_uebung(subtitle: str | None = None) -> str:
|
||||
"""Emit begin of übung box as raw latex fence."""
|
||||
display = "Jetzt selbst machen"
|
||||
inner = (
|
||||
f"\\begin{{guideuebung}}\n"
|
||||
f"{_label_line('guideuebung', 'nexttokengold', display)}\n"
|
||||
)
|
||||
if subtitle:
|
||||
# Section title as bold lead-in (label stays short for scanability)
|
||||
inner += f"\\textbf{{{escape_latex_plain(subtitle)}}}\\par\\vspace{{0.2em}}\n"
|
||||
return _latex_raw_block(inner).rstrip("\n")
|
||||
|
||||
|
||||
def _close_uebung() -> str:
|
||||
return _latex_raw_block(r"\end{guideuebung}").rstrip("\n")
|
||||
|
||||
|
||||
_FENCE_OPEN = re.compile(r"^(`{3,}|~{3,})")
|
||||
|
||||
|
||||
def _fence_marker(line: str) -> str | None:
|
||||
"""Return fence run (e.g. '```') if line opens/closes a fenced block."""
|
||||
m = _FENCE_OPEN.match(line)
|
||||
return m.group(1) if m else None
|
||||
|
||||
|
||||
def transform_uebungen(text: str) -> str:
|
||||
"""Wrap 'Jetzt selbst machen' blocks in guideuebung callouts."""
|
||||
lines = text.splitlines(keepends=False)
|
||||
out: list[str] = []
|
||||
i = 0
|
||||
n = len(lines)
|
||||
|
||||
while i < n:
|
||||
line = lines[i]
|
||||
hm = _UEBUNG_HEADING.match(line)
|
||||
if hm:
|
||||
title = hm.group("title").strip()
|
||||
out.append(_open_uebung(title))
|
||||
i += 1
|
||||
fence: str | None = None
|
||||
while i < n:
|
||||
nxt = lines[i]
|
||||
marker = _fence_marker(nxt)
|
||||
if fence is None and marker:
|
||||
fence = marker
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
continue
|
||||
if fence is not None:
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
if marker == fence:
|
||||
fence = None
|
||||
continue
|
||||
if _SECTION_STOP.match(nxt):
|
||||
break
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
out.append(_close_uebung())
|
||||
continue
|
||||
|
||||
im = _UEBUNG_INLINE.match(line)
|
||||
if im and not line.lstrip().startswith("#"):
|
||||
same_line_body = (im.group("body") or im.group("body2") or "").strip()
|
||||
out.append(_open_uebung())
|
||||
if same_line_body:
|
||||
out.append(same_line_body)
|
||||
i += 1
|
||||
fence = None
|
||||
while i < n:
|
||||
nxt = lines[i]
|
||||
marker = _fence_marker(nxt)
|
||||
if fence is None and marker:
|
||||
fence = marker
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
continue
|
||||
if fence is not None:
|
||||
# Inside fenced code: never treat # comments as headings
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
if marker == fence:
|
||||
fence = None
|
||||
continue
|
||||
if _UEBUNG_STOP.match(nxt) or _UEBUNG_HEADING.match(nxt):
|
||||
break
|
||||
if (
|
||||
nxt.strip() == ""
|
||||
and i + 1 < n
|
||||
and _UEBUNG_STOP.match(lines[i + 1])
|
||||
):
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
break
|
||||
out.append(nxt)
|
||||
i += 1
|
||||
out.append(_close_uebung())
|
||||
continue
|
||||
|
||||
out.append(line)
|
||||
i += 1
|
||||
|
||||
return "\n".join(out) + ("\n" if text.endswith("\n") else "")
|
||||
|
||||
|
||||
def _prepare_chapter(text: str) -> str:
|
||||
text = _strip_yaml_frontmatter(text)
|
||||
text = _TOC_RE.sub("", text, count=1)
|
||||
# Callouts before HTML-comment strip (markers none today; order reserved)
|
||||
text = transform_blockquotes(text)
|
||||
text = transform_uebungen(text)
|
||||
text = _HTML_COMMENT_RE.sub("", text)
|
||||
# Drop accidental markdown hard-breaks at end of list items (PDF spacing).
|
||||
text = _LIST_ITEM_HARDBREAK_RE.sub(r"\1", text)
|
||||
# Collapse 3+ blank lines.
|
||||
text = re.sub(r"\n{3,}", "\n\n", text)
|
||||
return text.strip() + "\n"
|
||||
|
||||
|
||||
def _strip_yaml_frontmatter(text: str) -> str:
|
||||
if not text.startswith("---"):
|
||||
return text
|
||||
end = text.find("\n---", 3)
|
||||
if end == -1:
|
||||
return text
|
||||
return text[end + 4 :].lstrip("\n")
|
||||
|
||||
|
||||
def pandoc_auto_id(title: str) -> str:
|
||||
"""Match Pandoc's default auto-identifier for a plain heading title."""
|
||||
s = title.lower()
|
||||
out: list[str] = []
|
||||
for ch in s:
|
||||
if ch.isalnum() or ch in "._-":
|
||||
out.append(ch)
|
||||
elif ch.isspace():
|
||||
out.append("-")
|
||||
s = "".join(out)
|
||||
s = re.sub(r"-{2,}", "-", s).strip("-")
|
||||
i = 0
|
||||
while i < len(s) and not s[i].isalpha():
|
||||
i += 1
|
||||
s = s[i:] if i < len(s) else "section"
|
||||
return s or "section"
|
||||
|
||||
|
||||
# Repo markdown uses ``[text](01-foo.md)`` / ``[text](01-foo.md#sec)``.
|
||||
# After concat into one ``book.md``, those must become in-document anchors
|
||||
# or PDF hyperlinks point at non-existent ``.md`` paths.
|
||||
_MD_FILE_LINK_RE = re.compile(
|
||||
r"\[([^\]]*)\]\("
|
||||
r"(?:\./)?"
|
||||
r"([^)\s#]+\.md)"
|
||||
r"(?:#([^)\s]+))?"
|
||||
r"\)"
|
||||
)
|
||||
|
||||
|
||||
def _first_h1_title(text: str) -> str | None:
|
||||
m = re.search(r"^#\s+(.+)$", text, re.MULTILINE)
|
||||
if not m:
|
||||
return None
|
||||
title = m.group(1).strip()
|
||||
# Drop explicit Pandoc attributes: ``{#id .class}``
|
||||
title = re.sub(r"\s*\{[^}]+\}\s*$", "", title).strip()
|
||||
return title or None
|
||||
|
||||
|
||||
def chapter_file_to_anchor() -> dict[str, str]:
|
||||
"""Map chapter basename → ``#``-anchor of its first H1 (Pandoc auto-id)."""
|
||||
mapping: dict[str, str] = {}
|
||||
for name in CHAPTER_ORDER:
|
||||
path = REPO_ROOT / name
|
||||
if not path.exists():
|
||||
continue
|
||||
title = _first_h1_title(path.read_text(encoding="utf-8"))
|
||||
if title:
|
||||
mapping[name] = pandoc_auto_id(title)
|
||||
return mapping
|
||||
|
||||
|
||||
def rewrite_chapter_file_links(text: str, file_to_id: dict[str, str]) -> str:
|
||||
"""Turn inter-chapter ``.md`` links into in-document ``#`` anchors for PDF.
|
||||
|
||||
Skips fenced ``{=latex}`` raw blocks: those already left Markdown land, and
|
||||
a bare ``#`` there is a LaTeX macro parameter (build failure).
|
||||
"""
|
||||
|
||||
def repl(m: re.Match[str]) -> str:
|
||||
label, path, frag = m.group(1), m.group(2), m.group(3)
|
||||
base = pathlib.PurePosixPath(path).name
|
||||
if frag:
|
||||
return f"[{label}](#{frag})"
|
||||
anchor = file_to_id.get(base)
|
||||
if anchor:
|
||||
return f"[{label}](#{anchor})"
|
||||
return m.group(0)
|
||||
|
||||
# Split on latex raw fences so we only rewrite real Markdown.
|
||||
parts = re.split(r"(```\{=latex\}.*?```)", text, flags=re.DOTALL)
|
||||
out: list[str] = []
|
||||
for part in parts:
|
||||
if part.startswith("```{=latex}"):
|
||||
out.append(part)
|
||||
else:
|
||||
out.append(_MD_FILE_LINK_RE.sub(repl, part))
|
||||
return "".join(out)
|
||||
|
||||
|
||||
def assemble(out_path: pathlib.Path) -> None:
|
||||
parts: list[str] = []
|
||||
for name in CHAPTER_ORDER:
|
||||
path = REPO_ROOT / name
|
||||
if not path.exists():
|
||||
raise SystemExit(f"Kapitel fehlt: {path}")
|
||||
body = _prepare_chapter(path.read_text(encoding="utf-8"))
|
||||
parts.append(body)
|
||||
|
||||
# Page break between chapters for clearer PDF chapters.
|
||||
joined = "\n\n\\newpage\n\n".join(parts).strip() + "\n"
|
||||
joined = rewrite_chapter_file_links(joined, chapter_file_to_anchor())
|
||||
|
||||
BUILD_DIR.mkdir(parents=True, exist_ok=True)
|
||||
out_path.write_text(joined, encoding="utf-8")
|
||||
print(
|
||||
f"Assembliert: {len(CHAPTER_ORDER)} Kapitel -> {out_path.relative_to(REPO_ROOT)}"
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Assemble practice book into build/book.md"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--out",
|
||||
type=pathlib.Path,
|
||||
default=DEFAULT_TARGET,
|
||||
help="Output path (default: build/book.md)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
assemble(args.out)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Resolve relative Markdown links in the Tight-Loop scope (stdlib only).
|
||||
|
||||
Default files: AGENTS.md, 0*.md–2*.md, templates/, checklists/.
|
||||
Skips http(s), mailto, bare #anchors. Ignores fenced code blocks.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
GLOBS = (
|
||||
"AGENTS.md",
|
||||
"0*.md",
|
||||
"1*.md",
|
||||
"2*.md",
|
||||
"templates/**/*.md",
|
||||
"checklists/**/*.md",
|
||||
)
|
||||
FENCE_RE = re.compile(r"^ {0,3}(`{3,}|~{3,})")
|
||||
LINK_RE = re.compile(r"(?<!\!)\[[^\]]*\]\(([^)]+)\)")
|
||||
|
||||
|
||||
def iter_scope() -> list[Path]:
|
||||
seen: set[Path] = set()
|
||||
out: list[Path] = []
|
||||
for pattern in GLOBS:
|
||||
for path in sorted(ROOT.glob(pattern)):
|
||||
if not path.is_file() or path.suffix != ".md":
|
||||
continue
|
||||
resolved = path.resolve()
|
||||
if resolved in seen:
|
||||
continue
|
||||
seen.add(resolved)
|
||||
out.append(path)
|
||||
return out
|
||||
|
||||
|
||||
def strip_fences(text: str) -> str:
|
||||
lines = text.splitlines(keepends=True)
|
||||
kept: list[str] = []
|
||||
fence: str | None = None
|
||||
for line in lines:
|
||||
if fence is None:
|
||||
match = FENCE_RE.match(line)
|
||||
if match:
|
||||
fence = match.group(1)[0]
|
||||
kept.append("\n" if line.endswith("\n") else "")
|
||||
continue
|
||||
kept.append(line)
|
||||
continue
|
||||
if FENCE_RE.match(line) and line.strip().startswith(fence):
|
||||
fence = None
|
||||
kept.append("\n" if line.endswith("\n") else "")
|
||||
return "".join(kept)
|
||||
|
||||
|
||||
def skip_url(url: str) -> bool:
|
||||
return url.startswith(
|
||||
("#", "http://", "https://", "mailto:", "ftp://", "tel:")
|
||||
)
|
||||
|
||||
|
||||
def check_file(path: Path) -> list[str]:
|
||||
text = strip_fences(path.read_text(encoding="utf-8"))
|
||||
errors: list[str] = []
|
||||
for match in LINK_RE.finditer(text):
|
||||
raw = match.group(1).strip()
|
||||
if not raw:
|
||||
errors.append(f"{path}: empty link target")
|
||||
continue
|
||||
url = raw.split()[0].strip("<>")
|
||||
if skip_url(url):
|
||||
continue
|
||||
file_part = url.split("#", 1)[0]
|
||||
if not file_part or not file_part.endswith(".md"):
|
||||
continue
|
||||
dest = (path.parent / file_part).resolve()
|
||||
try:
|
||||
dest.relative_to(ROOT)
|
||||
except ValueError:
|
||||
errors.append(f"{path}: {url} escapes repo root")
|
||||
continue
|
||||
if not dest.is_file():
|
||||
errors.append(f"{path}: {url} → missing {dest.relative_to(ROOT)}")
|
||||
return errors
|
||||
|
||||
|
||||
def main() -> int:
|
||||
errors: list[str] = []
|
||||
files = iter_scope()
|
||||
if not files:
|
||||
print("check_md_links: no files in scope", file=sys.stderr)
|
||||
return 2
|
||||
for path in files:
|
||||
errors.extend(check_file(path))
|
||||
if errors:
|
||||
print("\n".join(errors), file=sys.stderr)
|
||||
print(f"check_md_links: {len(errors)} broken link(s)", file=sys.stderr)
|
||||
return 1
|
||||
print(f"check_md_links: {len(files)} file(s) ok")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,425 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Post-build quality checks for the Coding-Agents-in-der-Praxis book PDF.
|
||||
|
||||
CLI:
|
||||
python3 scripts/check_pdf.py [--pdf PATH] [--mode ebook|print]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import zlib
|
||||
|
||||
REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||
DEFAULT_PDF = REPO_ROOT / "dist" / "collatz-vermutung.pdf"
|
||||
DEFAULT_PRINT_PDF = REPO_ROOT / "dist" / "collatz-vermutung-print.pdf"
|
||||
|
||||
# Print 6×9: soft page band (warn outside; eBook has no soft page limit)
|
||||
PRINT_SOFT_MIN_PAGES = 120
|
||||
PRINT_SOFT_MAX_PAGES = 320
|
||||
|
||||
# 6×9 in in PDF points (1 in = 72 pt)
|
||||
PRINT_W_PT = 6 * 72 # 432
|
||||
PRINT_H_PT = 9 * 72 # 648
|
||||
PRINT_SIZE_TOL_PT = 1.5
|
||||
|
||||
KEYWORDS = [
|
||||
"Collatz",
|
||||
"Vermutung",
|
||||
"Zyklus",
|
||||
"Stoppzeit",
|
||||
"3n+1",
|
||||
]
|
||||
|
||||
|
||||
def _print(result: str, label: str, detail: str = "") -> None:
|
||||
suffix = f" — {detail}" if detail else ""
|
||||
print(f"[{result}] {label}{suffix}")
|
||||
|
||||
|
||||
def _decompress_streams(data: bytes) -> list[str]:
|
||||
out: list[str] = []
|
||||
for m in re.finditer(rb"stream\r?\n(.*?)\r?\nendstream", data, re.S):
|
||||
try:
|
||||
out.append(zlib.decompress(m.group(1)).decode("latin-1", "ignore"))
|
||||
except Exception:
|
||||
continue
|
||||
return out
|
||||
|
||||
|
||||
def check_exists(pdf: pathlib.Path) -> bool:
|
||||
if not pdf.exists():
|
||||
_print("FAIL", "PDF exists", f"{pdf} nicht gefunden")
|
||||
return False
|
||||
size = pdf.stat().st_size
|
||||
if size == 0:
|
||||
_print("FAIL", "PDF non-empty", "Dateigröße ist 0 Bytes")
|
||||
return False
|
||||
_print("OK", "PDF exists", f"{pdf.name}, {size / 1024:.1f} KiB")
|
||||
return True
|
||||
|
||||
|
||||
def check_pages(data: bytes, mode: str) -> int:
|
||||
text = data.decode("latin-1", "ignore")
|
||||
counts = [int(m) for m in re.findall(r"/Count\s+(\d+)", text)]
|
||||
if counts:
|
||||
pages = max(counts)
|
||||
else:
|
||||
pages = 0
|
||||
for chunk in _decompress_streams(data):
|
||||
pages += len(re.findall(r"/Type\s*/Page[^s]", chunk))
|
||||
|
||||
if pages == 0:
|
||||
_print("WARN", "Page count", "konnte nicht geschätzt werden")
|
||||
return pages
|
||||
|
||||
# eBook: report only (no soft min/max). Print: soft band 120–320.
|
||||
if mode == "print":
|
||||
soft_min, soft_max = PRINT_SOFT_MIN_PAGES, PRINT_SOFT_MAX_PAGES
|
||||
if pages < soft_min:
|
||||
_print(
|
||||
"WARN",
|
||||
"Page count",
|
||||
f"~{pages} Seiten (unter Ziel {soft_min}–{soft_max})",
|
||||
)
|
||||
elif pages > soft_max:
|
||||
_print(
|
||||
"WARN",
|
||||
"Page count",
|
||||
f"~{pages} Seiten (über Ziel {soft_min}–{soft_max})",
|
||||
)
|
||||
else:
|
||||
_print(
|
||||
"OK",
|
||||
"Page count",
|
||||
f"~{pages} Seiten (Ziel {soft_min}–{soft_max})",
|
||||
)
|
||||
else:
|
||||
_print("OK", "Page count", f"~{pages} Seiten")
|
||||
return pages
|
||||
|
||||
|
||||
def check_fonts(pdf: pathlib.Path) -> None:
|
||||
pdffonts = shutil.which("pdffonts")
|
||||
if not pdffonts:
|
||||
_print("SKIP", "Font embedding", "pdffonts nicht installiert")
|
||||
return
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
[pdffonts, str(pdf)],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
_print("WARN", "Font embedding", f"pdffonts failed: {exc}")
|
||||
return
|
||||
|
||||
lines = [ln for ln in proc.stdout.splitlines() if ln.strip()]
|
||||
body = lines[2:] if len(lines) > 2 else []
|
||||
if not body:
|
||||
_print("WARN", "Font embedding", "keine Fonts gelistet")
|
||||
return
|
||||
|
||||
unembedded = 0
|
||||
for ln in body:
|
||||
parts = ln.split()
|
||||
# pdffonts columns: name type emb sub uni object ID
|
||||
if len(parts) >= 5 and parts[3] in {"no", "No"}:
|
||||
unembedded += 1
|
||||
if unembedded:
|
||||
_print("WARN", "Font embedding", f"{unembedded} Font(s) nicht eingebettet")
|
||||
else:
|
||||
_print("OK", "Font embedding", f"{len(body)} Fonts, eingebettet")
|
||||
|
||||
|
||||
def check_keywords(pdf: pathlib.Path) -> None:
|
||||
pdftotext = shutil.which("pdftotext")
|
||||
if not pdftotext:
|
||||
_print("SKIP", "Keywords", "pdftotext nicht installiert")
|
||||
return
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
[pdftotext, "-layout", str(pdf), "-"],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
_print("WARN", "Keywords", f"pdftotext failed: {exc}")
|
||||
return
|
||||
|
||||
text = proc.stdout
|
||||
missing = [k for k in KEYWORDS if k not in text]
|
||||
if missing:
|
||||
_print("WARN", "Keywords", f"fehlen: {', '.join(missing)}")
|
||||
else:
|
||||
_print("OK", "Keywords", f"{len(KEYWORDS)} Schlüsselbegriffe gefunden")
|
||||
|
||||
|
||||
def _pdfinfo_fields(pdf: pathlib.Path) -> dict[str, str]:
|
||||
pdfinfo = shutil.which("pdfinfo")
|
||||
if not pdfinfo:
|
||||
return {}
|
||||
try:
|
||||
proc = subprocess.run(
|
||||
[pdfinfo, str(pdf)],
|
||||
check=True,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
)
|
||||
except subprocess.CalledProcessError:
|
||||
return {}
|
||||
fields: dict[str, str] = {}
|
||||
for line in proc.stdout.splitlines():
|
||||
if ":" not in line:
|
||||
continue
|
||||
key, val = line.split(":", 1)
|
||||
fields[key.strip()] = val.strip()
|
||||
return fields
|
||||
|
||||
|
||||
def check_page_size_print(pdf: pathlib.Path) -> None:
|
||||
"""Expect ~6×9 in (432×648 pt)."""
|
||||
fields = _pdfinfo_fields(pdf)
|
||||
if not fields:
|
||||
_print("SKIP", "Page size (print)", "pdfinfo nicht verfügbar")
|
||||
return
|
||||
|
||||
size = fields.get("Page size", "")
|
||||
# e.g. "432 x 648 pts" or "432 x 648 pts (letter)"
|
||||
m = re.search(r"([\d.]+)\s*x\s*([\d.]+)\s*pts", size, re.I)
|
||||
if not m:
|
||||
_print("WARN", "Page size (print)", f"unparseable: {size!r}")
|
||||
return
|
||||
w, h = float(m.group(1)), float(m.group(2))
|
||||
ok_w = abs(w - PRINT_W_PT) <= PRINT_SIZE_TOL_PT
|
||||
ok_h = abs(h - PRINT_H_PT) <= PRINT_SIZE_TOL_PT
|
||||
if ok_w and ok_h:
|
||||
_print("OK", "Page size (print)", f"{w:.1f} × {h:.1f} pts (6×9 in)")
|
||||
else:
|
||||
_print(
|
||||
"FAIL",
|
||||
"Page size (print)",
|
||||
f"{w:.1f} × {h:.1f} pts — erwartet ~{PRINT_W_PT} × {PRINT_H_PT} (6×9 in)",
|
||||
)
|
||||
|
||||
|
||||
def check_pdf_version(pdf: pathlib.Path) -> None:
|
||||
fields = _pdfinfo_fields(pdf)
|
||||
if not fields:
|
||||
return
|
||||
ver = fields.get("PDF version", "?")
|
||||
pages = fields.get("Pages", "?")
|
||||
_print("OK", "PDF meta", f"version={ver}, pages={pages}")
|
||||
|
||||
|
||||
def check_print_assets() -> None:
|
||||
"""Soft checks on staged/source print assets (DPI readiness + gray stage)."""
|
||||
try:
|
||||
from PIL import Image
|
||||
except ImportError:
|
||||
_print("SKIP", "Print assets DPI", "Pillow nicht verfügbar")
|
||||
return
|
||||
|
||||
# Cover: prefer print-specific source, then staged gray (path-mirrored), else eBook
|
||||
cover_candidates = [
|
||||
REPO_ROOT / "assets" / "cover" / "cover-front-print.jpg",
|
||||
REPO_ROOT / "build" / "print-assets" / "assets" / "cover" / "cover-front.jpg",
|
||||
REPO_ROOT / "assets" / "cover" / "cover-front.jpg",
|
||||
]
|
||||
cover = next((p for p in cover_candidates if p.exists()), None)
|
||||
# Safe frame 5.4×8.4 in @ 300 DPI
|
||||
min_cover_w, min_cover_h = 1620, 2520
|
||||
if cover is None:
|
||||
_print("WARN", "Cover asset", "kein cover-front(-print).jpg gefunden")
|
||||
else:
|
||||
with Image.open(cover) as im:
|
||||
w, h = im.size
|
||||
if w >= min_cover_w and h >= min_cover_h:
|
||||
_print(
|
||||
"OK",
|
||||
"Cover asset DPI",
|
||||
f"{cover.relative_to(REPO_ROOT)} {w}×{h} (≥ {min_cover_w}×{min_cover_h})",
|
||||
)
|
||||
else:
|
||||
_print(
|
||||
"WARN",
|
||||
"Cover asset DPI",
|
||||
f"{cover.relative_to(REPO_ROOT)} {w}×{h} — Ziel ≥ {min_cover_w}×{min_cover_h} "
|
||||
f'(300 DPI im 0,30"-Safe-Frame)',
|
||||
)
|
||||
|
||||
# Figures: 1280 px @ Gin 0.87 ≈ 300 DPI; warn if many below threshold
|
||||
illus = REPO_ROOT / "assets" / "illustrations"
|
||||
min_fig_w = 1280 # matches prepare_print_assets MIN at Gin 0.87
|
||||
low: list[str] = []
|
||||
total = 0
|
||||
if illus.is_dir():
|
||||
for p in sorted(illus.glob("*.jpg")) + sorted(illus.glob("*.png")):
|
||||
if p.name.startswith("."):
|
||||
continue
|
||||
total += 1
|
||||
with Image.open(p) as im:
|
||||
w, _h = im.size
|
||||
if w < min_fig_w:
|
||||
low.append(f"{p.name} ({w}px)")
|
||||
if total == 0:
|
||||
_print("SKIP", "Figure assets", "keine Illustrations gefunden")
|
||||
elif not low:
|
||||
_print("OK", "Figure assets DPI", f"{total} Datei(en) ≥ {min_fig_w}px Breite")
|
||||
else:
|
||||
_print(
|
||||
"WARN",
|
||||
"Figure assets DPI",
|
||||
f"{len(low)}/{total} unter {min_fig_w}px — bei Gin 0,87 < ~300 DPI: "
|
||||
+ ", ".join(low[:6])
|
||||
+ ("…" if len(low) > 6 else ""),
|
||||
)
|
||||
|
||||
# Staged grayscale must mirror MD paths and be single-channel
|
||||
staged = REPO_ROOT / "build" / "print-assets" / "assets" / "illustrations"
|
||||
if not staged.is_dir():
|
||||
_print(
|
||||
"WARN",
|
||||
"Print gray stage",
|
||||
"build/print-assets/assets/illustrations fehlt — just print-assets?",
|
||||
)
|
||||
return
|
||||
not_gray: list[str] = []
|
||||
staged_n = 0
|
||||
for p in sorted(staged.glob("*.jpg")):
|
||||
staged_n += 1
|
||||
with Image.open(p) as im:
|
||||
if im.mode not in ("L", "1", "LA"):
|
||||
not_gray.append(f"{p.name}({im.mode})")
|
||||
if staged_n == 0:
|
||||
_print("WARN", "Print gray stage", "keine staged JPEGs")
|
||||
elif not_gray:
|
||||
_print(
|
||||
"FAIL",
|
||||
"Print gray stage",
|
||||
f"{len(not_gray)} nicht grayscale: " + ", ".join(not_gray[:8]),
|
||||
)
|
||||
else:
|
||||
_print("OK", "Print gray stage", f"{staged_n} staged JPEG(s), mode L")
|
||||
|
||||
|
||||
def check_print_pdf_images_gray(pdf: pathlib.Path) -> bool:
|
||||
"""Fail if embedded images are DeviceRGB (figures must be gray in print PDF).
|
||||
|
||||
Returns True when check fails (for exit code).
|
||||
"""
|
||||
if not shutil.which("pdfimages"):
|
||||
_print("SKIP", "PDF images gray", "pdfimages nicht verfügbar")
|
||||
return False
|
||||
try:
|
||||
out = subprocess.check_output(
|
||||
["pdfimages", "-list", str(pdf)],
|
||||
text=True,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
except (subprocess.CalledProcessError, OSError) as e:
|
||||
_print("SKIP", "PDF images gray", f"pdfimages fehlgeschlagen: {e}")
|
||||
return False
|
||||
|
||||
rgb = 0
|
||||
gray = 0
|
||||
other = 0
|
||||
for line in out.splitlines():
|
||||
# skip header lines; data rows start with page number
|
||||
parts = line.split()
|
||||
if len(parts) < 6 or not parts[0].isdigit():
|
||||
continue
|
||||
# columns: page num type width height color comp bpc ...
|
||||
color = parts[5].lower()
|
||||
if color in ("gray", "grey", "image-mask", "stencil"):
|
||||
gray += 1
|
||||
elif color in ("rgb", "cmyk", "icc"):
|
||||
rgb += 1
|
||||
else:
|
||||
other += 1
|
||||
|
||||
total = rgb + gray + other
|
||||
if total == 0:
|
||||
_print("WARN", "PDF images gray", "keine eingebetteten Bilder gefunden")
|
||||
return False
|
||||
if rgb > 0:
|
||||
_print(
|
||||
"FAIL",
|
||||
"PDF images gray",
|
||||
f"{rgb}/{total} Bild(er) farbig (rgb/cmyk) — resource-path muss "
|
||||
f"build/print-assets (assets/…-Spiegel) vor den RGB-Originalen auflösen",
|
||||
)
|
||||
return True
|
||||
_print("OK", "PDF images gray", f"{gray}/{total} gray, 0 rgb")
|
||||
return False
|
||||
|
||||
|
||||
def print_manual_notes() -> None:
|
||||
print()
|
||||
print("── Print QA notes (manuell prüfen) ──────────────────────────────")
|
||||
print("• Titelseite: Cover im ≥0,30\"-Safe-Frame (KDP-Außen ≥0,25\").")
|
||||
print("• Body-Ränder: inner 0,65\", outer 0,60\", top 0,70\", bottom 1,00\" (Footer-Ink ≈ 0,65\").")
|
||||
print("• Body 10 pt / Leading ~14,6 pt; Boxen/Code/Tabellen 9 pt.")
|
||||
print("• Figuren: Gin width=0,87\\linewidth → 1280px ≈ 300 DPI.")
|
||||
print("• Diagramme mit ehemals farbigem Kanal: K-03, K-08, K-09, K-05,")
|
||||
print(" K-12, M-10 — Kontrast und Linienunterscheidung im Grayscale-PDF.")
|
||||
print("• Breite Tabellen (Anhang B, Matrizen): Satzspiegel / Umbruch.")
|
||||
print("• Lange Codezeilen und Dateipfade: innerhalb der Ränder?")
|
||||
print("• Seitenzahlen außen unten; Kolumnentitel nicht im Gutter.")
|
||||
print("• KDP-Außenumschlag (Bleed/Spine) ist separat — dieses PDF = Interior.")
|
||||
print("• Optional: just pdf-print-optimize (Ghostscript Gray/prepress).")
|
||||
print("────────────────────────────────────────────────────────────────")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="QA checks for book PDF")
|
||||
parser.add_argument("--pdf", type=pathlib.Path, default=None)
|
||||
parser.add_argument(
|
||||
"--mode",
|
||||
choices=("ebook", "print"),
|
||||
default="ebook",
|
||||
help="ebook (default A4) or print (KDP 6×9)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
mode = args.mode
|
||||
pdf = args.pdf
|
||||
if pdf is None:
|
||||
pdf = DEFAULT_PRINT_PDF if mode == "print" else DEFAULT_PDF
|
||||
|
||||
ok = check_exists(pdf)
|
||||
if not ok:
|
||||
return 1
|
||||
|
||||
data = pdf.read_bytes()
|
||||
check_pages(data, mode)
|
||||
check_fonts(pdf)
|
||||
check_keywords(pdf)
|
||||
check_pdf_version(pdf)
|
||||
|
||||
failed = False
|
||||
if mode == "print":
|
||||
check_page_size_print(pdf)
|
||||
check_print_assets()
|
||||
if check_print_pdf_images_gray(pdf):
|
||||
failed = True
|
||||
# Re-run logic for exit code
|
||||
fields = _pdfinfo_fields(pdf)
|
||||
size = fields.get("Page size", "")
|
||||
m = re.search(r"([\d.]+)\s*x\s*([\d.]+)\s*pts", size, re.I)
|
||||
if m:
|
||||
w, h = float(m.group(1)), float(m.group(2))
|
||||
if abs(w - PRINT_W_PT) > PRINT_SIZE_TOL_PT or abs(h - PRINT_H_PT) > PRINT_SIZE_TOL_PT:
|
||||
failed = True
|
||||
print_manual_notes()
|
||||
|
||||
return 1 if failed else 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,266 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Prepare grayscale, high-contrast print assets for KDP interior PDF.
|
||||
|
||||
Writes gray JPEGs under build/print-assets/ mirroring the MD-relative paths
|
||||
(assets/illustrations/…, assets/cover/…). Pandoc --resource-path puts
|
||||
build/print-assets first, so ``assets/illustrations/foo.jpg`` resolves to the
|
||||
gray stage instead of the RGB original under repo root.
|
||||
|
||||
CLI:
|
||||
python3 scripts/prepare_print_assets.py [--force]
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import pathlib
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
from PIL import Image, ImageEnhance, ImageFilter, ImageOps
|
||||
|
||||
REPO_ROOT = pathlib.Path(__file__).resolve().parent.parent
|
||||
SRC_ILLUSTRATIONS = REPO_ROOT / "assets" / "illustrations"
|
||||
SRC_COVER = REPO_ROOT / "assets" / "cover"
|
||||
OUT_ROOT = REPO_ROOT / "build" / "print-assets"
|
||||
# Mirror MD paths: assets/illustrations/… and assets/cover/…
|
||||
OUT_ILLUSTRATIONS = OUT_ROOT / "assets" / "illustrations"
|
||||
OUT_COVER = OUT_ROOT / "assets" / "cover"
|
||||
# Legacy layout (pre path-mirror) — removed so stale color lookups cannot win
|
||||
_LEGACY_ILLUSTRATIONS = OUT_ROOT / "illustrations"
|
||||
_LEGACY_COVER = OUT_ROOT / "cover"
|
||||
|
||||
# Geometry must stay in sync with pdf/print/metadata.yaml + print-preamble Gin
|
||||
# text width = 6 − inner − outer = 6 − 0.65 − 0.60 = 4.75 in
|
||||
TEXT_WIDTH_IN = 4.75
|
||||
GIN_FRACTION = 0.87 # \setkeys{Gin}{width=0.87\linewidth}
|
||||
FIG_DISPLAY_IN = TEXT_WIDTH_IN * GIN_FRACTION # ≈ 4.1325 in
|
||||
|
||||
# Cover interior: 6×9 with 0.30" safety → safe frame ≈ 5.4 × 8.4 in
|
||||
COVER_SAFE_W_IN = 5.40
|
||||
COVER_SAFE_H_IN = 8.40
|
||||
COVER_MIN_W_PX = int(COVER_SAFE_W_IN * 300) # 1620
|
||||
COVER_MIN_H_PX = int(COVER_SAFE_H_IN * 300) # 2520
|
||||
|
||||
TARGET_DPI = 300
|
||||
MIN_WIDTH_300DPI = int(FIG_DISPLAY_IN * TARGET_DPI) # ≈ 1279
|
||||
|
||||
|
||||
def _to_print_gray(im: Image.Image) -> Image.Image:
|
||||
"""RGB/RGBA → print grayscale with contrast and mild sharpening."""
|
||||
if im.mode in ("RGBA", "LA") or (im.mode == "P" and "transparency" in im.info):
|
||||
rgba = im.convert("RGBA")
|
||||
bg = Image.new("RGBA", rgba.size, (255, 255, 255, 255))
|
||||
im = Image.alpha_composite(bg, rgba).convert("RGB")
|
||||
else:
|
||||
im = im.convert("RGB")
|
||||
|
||||
gray = ImageOps.grayscale(im)
|
||||
gray = ImageOps.autocontrast(gray, cutoff=1)
|
||||
gray = ImageEnhance.Contrast(gray).enhance(1.12)
|
||||
gray = gray.filter(ImageFilter.UnsharpMask(radius=0.8, percent=80, threshold=2))
|
||||
return gray
|
||||
|
||||
|
||||
def _process_figure(src: pathlib.Path, dest: pathlib.Path) -> dict:
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
with Image.open(src) as im:
|
||||
im.load()
|
||||
mode = im.mode
|
||||
w, h = im.size
|
||||
gray = _to_print_gray(im)
|
||||
gray.save(
|
||||
dest,
|
||||
format="JPEG",
|
||||
quality=92,
|
||||
optimize=True,
|
||||
dpi=(TARGET_DPI, TARGET_DPI),
|
||||
)
|
||||
|
||||
dpi_at_display = w / FIG_DISPLAY_IN if w else 0
|
||||
return {
|
||||
"src": src.name,
|
||||
"dest": str(dest.relative_to(REPO_ROOT)),
|
||||
"size": f"{w}x{h}",
|
||||
"mode_in": mode,
|
||||
"kind": "figure",
|
||||
"dpi_at_display": round(dpi_at_display),
|
||||
"low_res": w < MIN_WIDTH_300DPI,
|
||||
}
|
||||
|
||||
|
||||
def _pad_to_aspect(im: Image.Image, target_aspect: float, fill: int = 255) -> Image.Image:
|
||||
"""Letterbox image to target width/height ratio (white by default).
|
||||
|
||||
Tall eBook covers (narrower than 6×9) otherwise fill full textheight in the
|
||||
interior title page and force blank pages around the cover graphic.
|
||||
"""
|
||||
w, h = im.size
|
||||
if w <= 0 or h <= 0:
|
||||
return im
|
||||
current = w / h
|
||||
if abs(current - target_aspect) < 0.01:
|
||||
return im
|
||||
if current > target_aspect:
|
||||
# too wide → pad height
|
||||
new_w, new_h = w, int(round(w / target_aspect))
|
||||
else:
|
||||
# too tall/narrow → pad width
|
||||
new_w, new_h = int(round(h * target_aspect)), h
|
||||
canvas = Image.new(im.mode, (new_w, new_h), fill)
|
||||
canvas.paste(im, ((new_w - w) // 2, (new_h - h) // 2))
|
||||
return canvas
|
||||
|
||||
|
||||
def _process_cover(src: pathlib.Path, dest: pathlib.Path) -> dict:
|
||||
"""Grayscale cover; pad to 6×9, upscale to ≥300 DPI in safe-frame if needed."""
|
||||
dest.parent.mkdir(parents=True, exist_ok=True)
|
||||
with Image.open(src) as im:
|
||||
im.load()
|
||||
mode = im.mode
|
||||
w0, h0 = im.size
|
||||
gray = _to_print_gray(im)
|
||||
# 6×9 trim aspect so title-page includegraphics fits without page break
|
||||
before_pad = gray.size
|
||||
gray = _pad_to_aspect(gray, COVER_SAFE_W_IN / COVER_SAFE_H_IN, fill=255)
|
||||
padded = gray.size != before_pad
|
||||
w, h = gray.size
|
||||
upscaled = False
|
||||
|
||||
# Ensure enough pixels for 300 DPI inside the 0.30" safety frame
|
||||
need_w, need_h = COVER_MIN_W_PX, COVER_MIN_H_PX
|
||||
scale = max(need_w / w, need_h / h, 1.0)
|
||||
if scale > 1.0:
|
||||
nw, nh = int(round(w * scale)), int(round(h * scale))
|
||||
gray = gray.resize((nw, nh), Image.Resampling.LANCZOS)
|
||||
gray = gray.filter(
|
||||
ImageFilter.UnsharpMask(radius=1.0, percent=90, threshold=2)
|
||||
)
|
||||
w, h = gray.size
|
||||
upscaled = True
|
||||
|
||||
gray.save(
|
||||
dest,
|
||||
format="JPEG",
|
||||
quality=94,
|
||||
optimize=True,
|
||||
dpi=(TARGET_DPI, TARGET_DPI),
|
||||
)
|
||||
|
||||
dpi_safe = min(w / COVER_SAFE_W_IN, h / COVER_SAFE_H_IN) if w and h else 0
|
||||
return {
|
||||
"src": src.name,
|
||||
"dest": str(dest.relative_to(REPO_ROOT)),
|
||||
"size": f"{w}x{h}",
|
||||
"size_src": f"{w0}x{h0}",
|
||||
"mode_in": mode,
|
||||
"kind": "cover",
|
||||
"dpi_at_safe_frame": round(dpi_safe),
|
||||
"upscaled": upscaled,
|
||||
"padded_6x9": padded,
|
||||
"low_res": dpi_safe < TARGET_DPI - 5,
|
||||
}
|
||||
|
||||
|
||||
def _pick_cover_source() -> pathlib.Path | None:
|
||||
"""Prefer dedicated print cover; fall back to eBook front cover."""
|
||||
for name in ("cover-front-print.jpg", "cover-front.jpg"):
|
||||
p = SRC_COVER / name
|
||||
if p.exists():
|
||||
return p
|
||||
return None
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Prepare KDP print assets (grayscale)")
|
||||
parser.add_argument(
|
||||
"--force",
|
||||
action="store_true",
|
||||
help="Re-process even if output is newer than source",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not SRC_ILLUSTRATIONS.is_dir():
|
||||
print(f"[FAIL] missing {SRC_ILLUSTRATIONS}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
# Drop pre-mirror staging dirs so resource-path cannot hit stale trees.
|
||||
for legacy in (_LEGACY_ILLUSTRATIONS, _LEGACY_COVER):
|
||||
if legacy.is_dir():
|
||||
shutil.rmtree(legacy)
|
||||
|
||||
OUT_ILLUSTRATIONS.mkdir(parents=True, exist_ok=True)
|
||||
OUT_COVER.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
reports: list[dict] = []
|
||||
sources = sorted(SRC_ILLUSTRATIONS.glob("*.jpg")) + sorted(
|
||||
SRC_ILLUSTRATIONS.glob("*.png")
|
||||
)
|
||||
for src in sources:
|
||||
if src.name.startswith("."):
|
||||
continue
|
||||
# Keep extension when already JPEG; convert PNG → .jpg for print stage
|
||||
dest = OUT_ILLUSTRATIONS / (src.stem + ".jpg")
|
||||
if (
|
||||
not args.force
|
||||
and dest.exists()
|
||||
and dest.stat().st_mtime >= src.stat().st_mtime
|
||||
):
|
||||
reports.append({"src": src.name, "skipped": True})
|
||||
continue
|
||||
reports.append(_process_figure(src, dest))
|
||||
|
||||
cover_src = _pick_cover_source()
|
||||
if cover_src is not None:
|
||||
# MD/eBook cover name; print source may be cover-front-print.jpg
|
||||
cover_dest = OUT_COVER / "cover-front.jpg"
|
||||
if (
|
||||
args.force
|
||||
or not cover_dest.exists()
|
||||
or cover_dest.stat().st_mtime < cover_src.stat().st_mtime
|
||||
):
|
||||
reports.append(_process_cover(cover_src, cover_dest))
|
||||
else:
|
||||
reports.append({"src": cover_src.name, "skipped": True})
|
||||
|
||||
processed = [r for r in reports if not r.get("skipped")]
|
||||
skipped = [r for r in reports if r.get("skipped")]
|
||||
low_figs = [
|
||||
r for r in processed if r.get("kind") == "figure" and r.get("low_res")
|
||||
]
|
||||
covers = [r for r in processed if r.get("kind") == "cover"]
|
||||
|
||||
print(f"[OK] print assets → {OUT_ROOT.relative_to(REPO_ROOT)}")
|
||||
print(f" processed={len(processed)} skipped={len(skipped)}")
|
||||
print(
|
||||
f" figure display ≈ {FIG_DISPLAY_IN:.2f} in "
|
||||
f"({GIN_FRACTION:.0%} · {TEXT_WIDTH_IN:.2f} in text); "
|
||||
f"300 DPI needs ≥ {MIN_WIDTH_300DPI} px width"
|
||||
)
|
||||
if low_figs:
|
||||
print(
|
||||
f"[WARN] {len(low_figs)} figure(s) below ~300 DPI at print display width "
|
||||
f"(not upscaled; reduce Gin or re-render):"
|
||||
)
|
||||
for r in low_figs:
|
||||
print(
|
||||
f" - {r['src']}: {r['size']} "
|
||||
f"(~{r['dpi_at_display']} dpi @ {FIG_DISPLAY_IN:.2f} in)"
|
||||
)
|
||||
for r in covers:
|
||||
flag = "upscaled" if r.get("upscaled") else "native"
|
||||
print(
|
||||
f"[OK] cover {r['src']} → {r['size']} "
|
||||
f"(src {r.get('size_src', '?')}, {flag}, "
|
||||
f"~{r.get('dpi_at_safe_frame')} dpi @ safe frame)"
|
||||
)
|
||||
if r.get("upscaled"):
|
||||
print(
|
||||
"[WARN] cover was LANCZOS-upscaled for 300 DPI interim — "
|
||||
"prefer assets/cover/cover-front-print.jpg ≥ 1620×2520 native"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in new issue
Block a user