| .. | ||
| .gitignore | ||
| README.md | ||
| rq_c5a.py | ||
| rq_c5a_cli.py | ||
| test_c5a.py | ||
C5A — CONTRACT & STATE MACHINE v1
Phase: C5A (erste Phase des C5 Sync Service) Status: DONE (Contract & State Machine) — INAKTIV, NO-WRITE Architektur: FORGEJO MASTER → C5 SYNC SERVICE → TOLARIA DERIVED → SEARCH FULL REBUILD
C5A implementiert ausschließlich den Contract + die Sync State Machine + die persistente Progress-State-Struktur. Es ist eine deterministische, inaktive Python-Library + CLI + Testsuite — es führt keine externen Writes aus.
NO-WRITE GUARANTEE (verbindlich)
C5A kann NOCH NICHT:
- Tolaria schreiben
- Search rebuilden
- Forgejo schreiben
- produktiv pollen
- Netzwerk-Mutationen ausführen
Es gibt keine Netzwerk-/HTTP-/Socket-/Subprocess-Mutationsfunktionen in C5A.
Die No-Write-Guarantee wird statisch per assert_no_write_guarantee() bewiesen
(keine requests/urllib/http/socket/subprocess-Imports) und durch den
Test test_no_write_guarantee abgesichert.
State Machine
Normalzustände
DISCOVERED → VALIDATING → READY → PROPAGATING_TOLARIA → VERIFYING_TOLARIA → UPDATING_SEARCH → VERIFYING_SEARCH → APPLIED
Fehlerzustände
RETRY_PENDING, FAILED, DEAD, HUMAN_REVIEW_REQUIRED
Ordering
WAITING_FOR_PREDECESSOR — Commits werden nur in korrekter Reihenfolge
verarbeitet (parent_sha / last_applied_commit). Lücken werden nicht
übersprungen.
Kerninvariante
last_applied_commit wird NUR nach vollständigem Tolaria+Search PASS
fortgeschrieben (mark_applied wird nur nach VERIFYING_SEARCH → APPLIED
aufgerufen).
Commit Contract
Eine Verarbeitungseinheit = ein Forgejo Commit:
| Feld | Beschreibung |
|---|---|
commit_sha |
Primärschlüssel |
parent_sha |
Vorgänger (Ordering) |
discovered_at |
Zeitstempel |
sequence |
Reihenfolge |
status |
Sync-Zustand |
retry_count |
Retry-Zähler |
last_error / last_error_code |
Fehler + Reason Code |
created_at / updated_at |
Zeitstempel |
Pro Changed Object
object_id, path_before, path_after, operation, content_hash_before,
content_hash_after, metadata_hash_before, metadata_hash_after,
representation, state
Operation Model
CREATE, CONTENT_UPDATE, METADATA_UPDATE, STATE_UPDATE, RENAME, MOVE,
SOURCE_CANONICAL_RELATION_UPDATE, TAGS_UPDATE, SUPERSEDE, DELETE_REQUEST
DELETE_REQUEST bleibt Human-Gate — kein automatisches Hard Delete.
Idempotenz
Basis: commit_sha + object_id + operation + Hash-Checks.
| Ergebnis | Bedeutung |
|---|---|
ALREADY_APPLIED |
Commit bereits vollständig angewendet |
ALREADY_AT_TARGET |
Ziel-Hash bereits erreicht |
RETRY_SAFE |
Noch nicht angewendet, sicher zu verarbeiten |
CONFLICT |
Existiert, aber Hash weicht ab |
Doppelte Commit-Erkennung ist deterministisch.
Ordering
Commits nur in korrekter Reihenfolge. Fehlender Vorgänger → WAITING_FOR_PREDECESSOR
(Reason Code OUT_OF_ORDER_COMMIT). Nach Anwendung des Vorgängers wird der
Commit erneut validiert.
Failure / Retry State
max_retries = 5(konfigurierbar)- Backoff:
1 / 2 / 4 / 8 / 16Sekunden (gekappt) - Nach Max →
DEADoderHUMAN_REVIEW_REQUIRED - Kein Endlos-Retry
Persistence
SQLite (c5a.db), isoliert, restart-fest. Anforderungen erfüllt:
- atomic (SQLite-Transaktionen, WAL)
- restart-safe (neuer Store auf gleicher DB behält State)
- inspectable (CLI
health,list-commits,commit-status) - backupbar (einzelne Datei)
- keine externe DB nötig
- kein Trading-/Forgejo-DB-Coupling (eigene DB)
Bootstrap State
UNINITIALIZED → RECONCILING → BASELINE_READY → ACTIVE
Baseline darf nur aus BASELINE_READY gesetzt werden (Master↔Tolaria-
Reconciliation muss sauber sein). In C5A wird keine produktive Baseline
gesetzt.
Reason Codes (geschlossene Menge)
UNEXPECTED_TOLARIA_DRIFT, ID_COLLISION, UNKNOWN_OBJECT_ID, INVALID_SCHEMA,
DANGLING_DERIVED_FROM, AMBIGUOUS_DELETE, UNKNOWN_LEGACY_OBJECT,
AUTH_FAILURE, SEARCH_REBUILD_FAILURE, TOLARIA_UNAVAILABLE,
FORGEJO_UNAVAILABLE, OUT_OF_ORDER_COMMIT, SECRET_DETECTED
Kein freier String-Wildwuchs als einziges Fehlerformat — unbekannte Reason Codes
werden abgelehnt (InvalidReasonCodeError).
Security Boundary (dokumentiert, NICHT implementiert)
- Forgejo credential: READ ONLY (C5A hält keinen Forgejo-Write)
- Tolaria write: nur später C5 Service
- Search rebuild: nur C5 Service Token
- Agents: keine direkten Tolaria-/Search-Admin-Writes
- Netzwerk-Härtung wird später beim Deployment umgesetzt, NICHT jetzt
Health Contract
status, bootstrap_state, last_seen_commit, last_applied_commit,
pending_commits, failed_commits, dead_commits, human_review_required,
forgejo_status, tolaria_status, search_status, drift_count,
last_success_at, last_error_code
C5A führt keine echten externen Health-Probes aus (rein State-Machine) —
forgejo_status/tolaria_status/search_status sind UNKNOWN.
CLI
export C5A_DB=/path/to/c5a.db # default: ./c5a.db
python3 rq_c5a_cli.py health
python3 rq_c5a_cli.py bootstrap-state
python3 rq_c5a_cli.py bootstrap-transition --to RECONCILING
python3 rq_c5a_cli.py set-baseline --commit <sha>
python3 rq_c5a_cli.py ingest-commit --json <file>
python3 rq_c5a_cli.py process-commit --json <file>
python3 rq_c5a_cli.py list-commits [--status <s>]
python3 rq_c5a_cli.py commit-status --sha <sha>
python3 rq_c5a_cli.py no-write-check
Tests
python3 test_c5a.py # 25 PASS / 0 FAIL
Abgedeckte Fälle: normal commit lifecycle, multi-object commit, duplicate commit, already-applied, out-of-order commit, missing predecessor, retry progression, max retry → DEAD, human gate transition, restart/reload persistence, state corruption handling, idempotency, delete request → human gate, dangling relation → human gate, unexpected drift → human gate, no-write guarantee, bootstrap lifecycle, baseline-only-from-BASELINE_READY, reason codes closed set, operations closed set, health contract fields, last_applied-only-after-full-pass, retry available bound, backoff sequence, invalid reason code rejected.
Dateien
rq_c5a.py— Kern-Library (Store + State Machine + No-Write-Check)rq_c5a_cli.py— CLItest_c5a.py— Testsuite (25 Tests)README.md— diese Datei