diff --git a/.gitignore b/.gitignore index ae2ea3b..decd481 100644 --- a/.gitignore +++ b/.gitignore @@ -90,3 +90,7 @@ id_ed25519* *.orig *.rej +# OS- & Editor-Reste +.DS_Store +*.swp +*.swo diff --git a/CHANGELOG.md b/CHANGELOG.md index a495eb3..dd7ba43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ ## [Unreleased] +- **Pfad A Technische Hygiene, Windows Quickstart Runner-Härtung, CI Workflow-Prüfung & Vertragstest-Wartung [G 2026-10-31]:** + - **Windows & Cross-Platform Quickstart Runner-Härtung (`tests/test_metadata.py`):** Absicherung des Subprozess-Aufrufs in `test_runnable_python_quickstart_in_readmes` via `-X utf8` und `PYTHONIOENCODING=utf-8` zur Verhinderung plattformabhängiger `UnicodeDecodeError` / `TypeError`-Abbrüche bei deutschen Umlauten auf Windows cp1252-Systemen. + - **`.gitignore`-Härtung:** Ergänzung um temporäre Editor- und OS-Dateien (`*.swp`, `*.swo`, `.DS_Store`). + - **Vertragstest-Erweiterung (`tests/test_metadata.py`):** Neuer Vertragstest `test_pfad_a_hygiene_20261031_recency` zur Validierung der kontinuierlichen Hygiene-Dokumentation; Gesamtsuite auf 164 Tests und 43 Subtests erweitert (100% grün). + - **Version-Freeze Disziplin:** Version 0.4.0 strikt eingefroren per T-20260920-167562623. + - **Pfad B Marketing, Discoverability, 20/20 GitHub Topics Saturation & Runnable Python Quickstart [G 2026-10-18]:** - **GitHub Topics & Discoverability Sättigung (20/20):** Repository-Topics auf GitHub via CLI (`gh repo edit`) auf das Maximum von 20 Topics gesättigt (`agent-framework`, `crdt`, `data-integrity`, `data-synchronization`, `database-sync`, `distributed-systems`, `edge-computing`, `last-write-wins`, `llm-agents`, `local-first`, `offline-first`, `offline-sync`, `privacy-first`, `python`, `snapshot-sync`, `sqlite`, `sqlite-sync`, `sync`, `sync-master`, `zero-dependency`). - **PEP 621 Keywords Harmonisierung in `pyproject.toml`:** Erweiterung der `keywords`-Liste von 9 auf 20 strukturierte Discoverability-Keywords in vollständiger Parität mit den GitHub-Topics. diff --git a/README.md b/README.md index f06dcc6..04bb966 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ [![CI](https://github.com/ellmos-ai/sqlite-transit-sync/actions/workflows/ci.yml/badge.svg)](https://github.com/ellmos-ai/sqlite-transit-sync/actions/workflows/ci.yml) [![Version](https://img.shields.io/badge/version-0.4.0-blue.svg)](CHANGELOG.md) -[![Tests](https://img.shields.io/badge/tests-163%20passed%20%7C%2043%20subtests%20%7C%20100%25%20green-brightgreen.svg)](#tests) -[![Verified: 2026-10-18](https://img.shields.io/badge/verified-2026--10--18-blue.svg)](#tests) +[![Tests](https://img.shields.io/badge/tests-164%20passed%20%7C%2043%20subtests%20%7C%20100%25%20green-brightgreen.svg)](#tests) +[![Verified: 2026-10-31](https://img.shields.io/badge/verified-2026--10--31-blue.svg)](#tests) [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://www.python.org/) [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-informational.svg)](#) [![Privacy](https://img.shields.io/badge/privacy-100%25%20Offline%20%7C%20Zero--Egress-brightgreen.svg)](#) diff --git a/README_de.md b/README_de.md index d7b3268..90b14d8 100644 --- a/README_de.md +++ b/README_de.md @@ -4,8 +4,8 @@ [![CI](https://github.com/ellmos-ai/sqlite-transit-sync/actions/workflows/ci.yml/badge.svg)](https://github.com/ellmos-ai/sqlite-transit-sync/actions/workflows/ci.yml) [![Version](https://img.shields.io/badge/version-0.4.0-blue.svg)](CHANGELOG.md) -[![Tests](https://img.shields.io/badge/tests-163%20passed%20%7C%2043%20subtests%20%7C%20100%25%20green-brightgreen.svg)](#tests-und-qualitaetssicherung) -[![Verified: 2026-10-18](https://img.shields.io/badge/gepr%C3%BCft-2026--10--18-blue.svg)](#tests-und-qualitaetssicherung) +[![Tests](https://img.shields.io/badge/tests-164%20passed%20%7C%2043%20subtests%20%7C%20100%25%20green-brightgreen.svg)](#tests-und-qualitaetssicherung) +[![Geprüft: 2026-10-31](https://img.shields.io/badge/gepr%C3%BCft-2026--10--31-blue.svg)](#tests-und-qualitaetssicherung) [![Python Version](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://www.python.org/) [![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS-informational.svg)](#) [![Privacy](https://img.shields.io/badge/privacy-100%25%20Offline%20%7C%20Zero--Egress-brightgreen.svg)](#) diff --git a/llms.txt b/llms.txt index 3bb41b9..9d3d53c 100644 --- a/llms.txt +++ b/llms.txt @@ -2,7 +2,7 @@ > Local-first SQLite synchronization through verified transit snapshots and configurable row-level merge policies. Extracted from the BACH ProSync architecture for standalone, zero-dependency Python projects. -- Last-checked: 2026-10-18 +- Last-checked: 2026-10-31 - Version: 0.4.0 - Module status: `development`; visibility projection: `public-candidate`; release gate: `LOCKED`. - Metadata contract: `METADATA_CONTRACT.md` (version, status and verification authority). @@ -16,7 +16,7 @@ ## System Overview -`sqlite-transit-sync` is a Python 3.10+ library (zero dependencies for merge mode; the optional Republica mode adds `cryptography`) and CLI for synchronizing local SQLite databases across untrusted or asynchronous file transports (shared folders, object-store mounts, removable drives, or sync-master yards). Includes ownership-aware snapshot retention policies, HMAC-SHA256 authentication, strict read-only application projection verification, and synthetic BACH golden comparison. Verified passing test suite on 2026-10-18 (100% green: 160 passed, 43 subtests). +`sqlite-transit-sync` is a Python 3.10+ library (zero dependencies for merge mode; the optional Republica mode adds `cryptography`) and CLI for synchronizing local SQLite databases across untrusted or asynchronous file transports (shared folders, object-store mounts, removable drives, or sync-master yards). Includes ownership-aware snapshot retention policies, HMAC-SHA256 authentication, strict read-only application projection verification, and synthetic BACH golden comparison. Verified passing test suite on 2026-10-31 (100% green: 164 passed, 43 subtests). It avoids live SQLite database locking over file sync by using: 1. Online consistent snapshots via SQLite Backup API (`sqlite3.Connection.backup`). diff --git a/tests/test_metadata.py b/tests/test_metadata.py index f2a26c1..2dd8464 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -1,4 +1,5 @@ import json +import os import re import subprocess import sys @@ -819,10 +820,11 @@ def test_runnable_python_quickstart_in_readmes(self): ] self.assertEqual(1, len(examples)) result = subprocess.run( - [sys.executable, "-c", examples[0]], cwd=ROOT, + [sys.executable, "-X", "utf8", "-c", examples[0]], cwd=ROOT, capture_output=True, text=True, encoding="utf-8", timeout=30, + env=dict(os.environ, PYTHONIOENCODING="utf-8"), ) - self.assertEqual(0, result.returncode, result.stdout + result.stderr) + self.assertEqual(0, result.returncode, f"stdout: {result.stdout}\nstderr: {result.stderr}") def test_marketing_log_and_changelog_pfad_b_recency(self): """CHANGELOG.md and MARKETING-LOG.txt must record the 2026-10-18 Pfad B audit.""" @@ -834,6 +836,12 @@ def test_marketing_log_and_changelog_pfad_b_recency(self): self.assertIn("2026-10-18", mkt) self.assertIn("12. PFAD B DISCOVERABILITY", mkt) + def test_pfad_a_hygiene_20261031_recency(self): + """CHANGELOG.md must record the 2026-10-31 Pfad A audit.""" + changelog = (ROOT / "CHANGELOG.md").read_text(encoding="utf-8") + self.assertIn("2026-10-31", changelog) + self.assertIn("Pfad A Technische Hygiene", changelog) + if __name__ == "__main__": unittest.main()