• v2.1.1 f63a72cb24

    v2.1.1
    CI / verify (push) Successful in 42s
    Release / release (push) Successful in 37s
    Stable

    torben released this 2026-09-01 15:06:29 +00:00 | 107 commits to main since this release

    2.1.1 - 2026-09-01 - raw_dir-Fixture kappt config.ROOT; letzte private Fixture-Namen ersetzt

    Author: Torben Nehmer

    Der erste CI-Lauf nach der Korpus-Bereinigung wurde rot, während dieselbe Suite lokal grün
    blieb: test_legacy_source_pages_flags_url_and_directory scheiterte mit
    KeyError: 'Source - DirBacked'.

    Die Ursache ist keine Testschwäche, sondern eine Umgebungsabhängigkeit. Der Test legt eine
    Quellenseite mit source: raw/documents an und erwartet, dass legacy_source_pages() sie als
    „directory, not a file" meldet. Die Prüfung dort ist (config.ROOT / legacy).is_dir() — sie
    löst also gegen das echte Repo-Wurzelverzeichnis auf, während die raw_dir-Fixture ihren
    Baum unter tmp_path baut. Der Test war nie hermetisch; er bestand, weil dieser Checkout
    zufällig ein raw/documents/ besaß.

    Die Korpus-Bereinigung hat dieses Verzeichnis geleert. Git verfolgt keine leeren Verzeichnisse,
    also verschwand es im CI-Checkout und blieb im lokalen Arbeitsbaum stehen — grün hier, rot
    dort, ohne dass sich am Test etwas geändert hätte.

    Geschlossen in der Fixture, nicht im Test. raw_dir setzt jetzt config.ROOT auf
    tmp_path. Das ist dieselbe Bauart und dasselbe Argument wie bei hermetic_environment
    (Gitea #8): Wenn eine Umgebungsabhängigkeit lokal unsichtbar ist, gehört sie an der Stelle
    geschlossen, die alle Tests erreicht, statt bei dem einen, der zufällig darüber stolpert.
    Nachgewiesen, indem raw/documents/ lokal entfernt und die Suite erneut gefahren wurde — 38
    Provenance-Tests grün ohne das Verzeichnis, vorher rot.

    Fixture-Namen. Die Suite benutzte weiterhin reale Systemnamen der Ursprungsinstanz als
    Fixture-Bezeichner (atlantis, abydos, Nathan, hermes, ecodms, Opa Hasso). In einem
    öffentlichen Repo beschreiben sie nichts, verraten aber die Namensgebung einer privaten
    Umgebung. Ersetzt durch aurora, almanac, Borealis, gateway, docstore. gdeploy
    bleibt: die Seite existiert im öffentlichen Korpus.

    Dateien: tools/chemenu/tests/conftest.py (raw_dir), sämtliche Testdateien mit
    Fixture-Namen.

    Downloads
  • v2.1.0 18ae28f918

    v2.1.0
    CI / verify (push) Failing after 32s
    Release / release (push) Successful in 38s
    Stable

    torben released this 2026-09-01 14:30:30 +00:00 | 108 commits to main since this release

    2.1.0 - 2026-09-01 - Dual-Lizenz AGPL-3.0/CC-BY-4.0, und ein Leak-Canary fuer dist export

    Author: Torben Nehmer

    Das Repo hatte keine Lizenz. Für ein Repo, das privat auf der eigenen Gitea liegt, ist das
    folgenlos; für eines, das veröffentlicht werden soll, hebt es den Zweck der Veröffentlichung
    auf — ohne Lizenz gilt „alle Rechte vorbehalten", und niemand darf eine Instanz aufsetzen.

    Zwei Hälften, zwei Lizenzen. LICENSE trägt die AGPL-3.0 und gilt für den Stack
    (tools/, types/); LICENSE-CONTENT trägt CC-BY-4.0 und gilt für die Inhalte (kb/,
    raw/, instructions/, die CONTRACT.md-Ebene, die Prosa im Wurzelverzeichnis). Die
    Aufteilung folgt dem Vorbild der vendorten Commonplace-Basis, kehrt aber deren Dateinamen um:
    Die Copyleft-Hälfte heißt LICENSE, weil das die Lizenz ist, die eine Forge für das Repository
    meldet — und wer eine Copyleft-Pflicht übersieht, wird dadurch geschädigt, wer eine zu viel
    sieht, nicht.

    Die Affero-Variante statt der einfachen GPL, weil Issue #19 den Stack als MCP-Frontend
    erreichbar machen will. Bei der GPL schuldet nichts, wer nur einen Dienst betreibt statt
    Software zu verteilen; genau dieser Weg ist der, den dieses Projekt einschlägt.

    Die Grenze wird nicht aufgeschrieben. Welche Datei zu welcher Hälfte gehört, ist der
    Dateiplan, den dist export ohnehin berechnet. NOTICE verweist darauf, statt eine zweite
    Pfadliste anzulegen, die drifted (Invariante 8). NOTICE trägt außerdem die Attribution für
    commonplace (zby, CC-BY-4.0 Inhalte + MIT Code), die CC-BY verlangt.

    dist export liefert die Lizenzen mit — und weigert sich sonst. Die drei Dateien stehen
    jetzt in ROOT_FILES, aber nicht nur dort: REQUIRED_ROOT_FILES macht sie zur Bedingung.
    Jeder andere ROOT_FILES-Eintrag wird if source.is_file() kopiert und sonst stillschweigend
    übersprungen — richtig für INSTALL.md, das es lange nicht gab, und falsch für eine Lizenz:
    Ein Export, der sie weglässt, übergibt einen AGPL-tools/-Baum ohne Lizenztext, und das ist
    eine Verletzung, sobald die empfangende Instanz irgendwo öffentlich landet.

    Der Leak-Canary. find_leaks() prüft den fertigen Plan gegen das, was er nie enthalten
    darf: eine ausgefüllte USER.md/SOUL.md/ENVIRONMENT.md, etwas unter instructions/dev/,
    eine kb/-Seite oder eine raw/-Quelle. Drei getrennte Allowlists entscheiden bisher, was
    build_plan kopiert, und jede hält nur, solange sich beim Editieren jemand an die Regel
    erinnert hat — nichts prüfte das Ergebnis nach. export bricht jetzt ab, wenn der Plan etwas
    davon trägt, mit dem Hinweis, die Allowlist zu reparieren statt Dateien aus dem Ziel zu löschen.

    Die Prüfung ist bewusst strukturell und nicht textbasiert. Ein Muster-Scan auf Hostnamen
    oder IP-Literale wurde erwogen und verworfen: Der eigene Host steht legitim in INSTALL.md und
    version.py, ein solcher Scan müsste also genau die Zeichenkette ausnehmen, nach der er sucht —
    oder bei jedem Export Fehlalarm geben.

    Beispiele neutralisiert. Hilfetexte, Docstrings und Contract-Beispiele nannten reale
    Seiten und Pfade der Ursprungsinstanz (Quellenseiten und Pfade
    aus dem privaten Korpus). In einer
    Distribution ist das nicht nur unpassend, sondern verrät den Inhalt der Instanz, die sie gebaut
    hat. Ersetzt durch Beispiele aus dem verbleibenden öffentlichen Korpus.

    Dateien: LICENSE, LICENSE-CONTENT, NOTICE (neu), config.LICENSE_FILES,
    dist_cmd.REQUIRED_ROOT_FILES, dist_cmd.find_leaks(), Lizenzabschnitt in README.md,
    sechs neue Tests in test_dist_cmd.py; Beispiel-Neutralisierung in cite_cmd.py,
    page_ops.py, work_cmd.py, provenance.py, search/ripgrep.py, work/CONTRACT.md,
    instructions/session-setup.md und zwei Testdateien.

    Downloads