API-Changelog und Migration Guides

Release Notes für kompatible v1-Änderungen, Deprecation Notices und Migration-Guide-Vorlagen stehen neben OpenAPI, Reference und SDK Source, damit Clients nicht nur Endpoints, sondern auch die Contract History verfolgen können.

Release Notes

Jede kompatible Public-API-Auslieferung erhält einen Eintrag mit affected operationIds, additive fields, documentation examples und validation gates. Breaking removal braucht eine neue major version oder einen abgeschlossenen deprecation path.

Änderungsklassifizierung

Jeder Eintrag verwendet eine Kompatibilitätskategorie, damit Integratoren Ergänzungen, Migrationen, neue Hauptversionen und Sicherheitsmaßnahmen unterscheiden können.

Additiv
Kompatible optionale Felder oder Operationen mit synchronisierten OpenAPI-, SDK-, Beispiel- und Toleranznachweisen.
Veraltet
Der alte Ablauf bleibt während der Ankündigungsfrist verfügbar, während Ersatz, Telemetrie, Migration und Support veröffentlicht sind.
Brechend oder neue Hauptversion
Eine inkompatible Entfernung oder Bedeutungsänderung erscheint nur in einer neuen Hauptversion oder nach dem vollständigen Deprecation-Pfad.
Sicherheit
Sicherheitshinweise nennen Auswirkungen und nötige Client-Aktionen ohne ausnutzbare Details. Unsichere Kompatibilität folgt dem Notfallmigrationsprozess.
Stable candidateAdditiv

SLO, Freshness und Capacity Budgets

Die Public API besitzt jetzt numerische Produkt-SLOs, starkes If-Match für veränderliche Writes und Admission Budgets vor Provider Signing.

  • Ziele: Availability ≥99,9 %, Latency p95 ≤2000 ms, Catalog p95 ≤15 s, Search Index p95 ≤1800 s, RPO ≤24 h und RTO ≤4 h; Warning/Critical Alerts feuern vor dem Breach.
  • Mod- und ModVersion-PATCH benötigen starkes If-Match und liefern einen neuen ETag. Fehlend liefert 428; malformed, weak, wildcard oder list values liefern 412 ohne Mutation; ein gültiger stale value liefert 412 mit aktuellem ETag. Retained SDKs bewahren Problem Details und Status.
  • Multipart verwendet nach einem Live-R2-Capacity-Probe standardmäßig 16 MiB × 4. Primary und Fallback Download Admission verlangen authoritative size und begrenzen Actor-/Client-Concurrency sowie Byte Buckets vor teurem Signing; Leases erholen sich nach Fehler oder Ablauf.
Stable candidateAdditiv

Universelle Domain-IDs und Lifecycle

Alle dreizehn öffentlichen Entitäten besitzen jetzt einheitliche opaque UUIDs, Ownership-/State-Regeln, Tombstone/410-Non-Reuse und einen unveränderlichen Published-Version-Snapshot, ohne Legacy-Aliase zu entfernen.

  • Game, Mod, ModVersion, Artifact, Blob, UploadSession, DownloadGrant, User, Team, Dependency, Job, WebhookSubscription und WebhookDelivery besitzen getrennte UUIDs und fail-closed State Machines. Rename erhält die Identität; Slug, Dateiname, URL, Storage Key, ETag oder Hash identifizieren keine Ressource.
  • Archive kann wiederhergestellt werden; dauerhafte Löschung hinterlässt einen Tombstone und liefert 410. Weder UUID noch Quellbindung werden wiederverwendet; eine unbekannte ID liefert 404.
  • Die erste Veröffentlichung speichert einen kanonischen Snapshot und SHA-256. Semantische Felder sind unveränderlich; Restore verlangt den exakten Snapshot und aktuelle Upload-Trust-Gates. lifecycle_version schützt parallele Updates. Alte uploaded/quarantined/approved/rejected Werte bleiben Kompatibilitäts-Aliase.
Stable candidateAdditiv

Fail-closed compensation boundaries

PR-F2.6.6 und PR-F2.6.7 definieren Replay und Recovery für Provider-Upload-Commit, Ready-Binding, Publish/Outbox und Trust-Enqueue-Checkpoints, ohne Trust- oder Publication-Preconditions abzuschwächen.

  • Eine cross-provider transaction wird nicht behauptet. Ein once-only Generation-Byte-Budget-Checkpoint liegt vor einer atomaren Session/File/upload.accepted Reservation; Replay dazwischen verwendet dasselbe Budget-Ergebnis. Jeder single PUT liefert signed If-None-Match: * und maximal eine 900-second URL Lease, die nach Signing und vor Response unter Row Lock checkpointed wird; ein abort-winning Checkpoint verwirft die URL. Ein conditional 412 führt zu complete für authoritative HEAD/Seal/SHA-256-Prüfung. Danach kopiert ein Session-Level Claim den exakten Client-Source-ETag bedingt in einen write-once server-only Seal vor dem queued scan checkpoint.
  • Heartbeat-backed Claim Tokens grenzen jede Scan-Mutation ab. Ready, Quarantine und Rejection committen Session/File/Job State, Audit und kanonisches Event jeweils in einer Database Transaction; Terminal Replay lädt und validiert dieses Envelope exakt. Vor Provider-Konfiguration oder normalen Claims stellt ein begrenzter reiner Datenbank-Sweep stale Max-Attempt Claims ohne erneute Scan-/Provider-Arbeit wieder her: Kohärenter State wechselt atomar in canonical Manual Review/Quarantine, inkohärenter State setzt nur den exakten Job für sichtbare manuelle Intervention terminal auf Failed. Same-SHA Final Promotion verwendet einen dauerhaften SHA/Bucket/Key Claim, canonical MIME und cf-copy-destination-if-none-match: *; ein fresh duplicate wartet oder übernimmt den ready Blob ohne normalen scan attempt. Das Polling ist exponentiell und pro Claim auf 15 Minuten begrenzt. Die ersten zwei dauerhaften token-fenced Yields stellen den normalen Attempt atomar wieder her und requeue-en mit datenbankbestimmtem Jitter von 30 bis 60 Sekunden; der dritte erstellt atomar Manual Review und Quarantäne mit exact Lost-Response-Replay, statt unbegrenzt weiter zu versuchen. Lost Copy Response Recovery verlangt Exact HEAD und einen nonblank ETag. Eine content-addressed final copy wird erst nach accessible attested blob und atomic Ready/Audit/file.ready Binding ready. Transactional publish und durable outbox teilen ebenfalls eine Transaction. Quarantine scan.completed und späteres file.ready behalten getrennte Identitäten. Die Account-Inbox-Benachrichtigung ist kein Lifecycle Acknowledgement.
  • Nach einer verlorenen Antwort erhält derselbe Idempotency-Key nur denselben Generation Claim zurück und konvergiert ohne doppelte Budget-, Audit-, Job-, Terminal-Event- oder Outbox-Effekte. Für Single Cleanup schreibt durable Stage 1 bedingt einen zero-byte tombstone und prüft Provider ETag, LastModified, Metadata Token und size=0; der Fence bleibt bis zur latest URL Lease und mindestens 16 Minuten. Stage 2 löscht Staging exakt, prüft es per HEAD und schließt DB ab; Crash Replay setzt den Stage fort. Multipart Cleanup bricht und relistet Exact-Key Uploads, alle Seal-Claim-Keys werden gelöscht und geprüft, Quarantäne bleibt erhalten. Desired CORS enthält If-None-Match, und der Object-Level Probe bestätigt Conditional Copy plus Late-PUT Tombstone Rejection, aber live CORS/lifecycle/lock evidence bleibt BLOCKED bis CLOUDFLARE_API_TOKEN, MODDINGFLOW_R2_FINAL_LOCK_MIN_SECONDS und MODDINGFLOW_R2_ALLOWED_BROWSER_ORIGINS vorliegen; ein live Deployment wird nicht behauptet. Eine unbound final copy bleibt non-ready und never publishable bis zur PR-F3.13 reference-aware legal-hold-safe deletion. Numeric freshness bleibt PR-F2.6.3, deployed webhook enablement bleibt PR-F8.14.
Stable candidateAdditiv

Managed artifact expansion

Optional PublicModVersion.artifacts ergänzt vollständige Metadaten für ein managed primary artifact und behält artifact_ids als stabile v1-Verknüpfung.

  • Expansion ist nur bei size_bytes > 0, exaktem sha256/hashes.sha256, einem current upload-session match auf file_id und final_blob_id, actual AV scan_status=clean, lifecycle=ready, publication state=published und managed resolve eligibility verfügbar.
  • Das vollständige Artifact enthält role/category, display und nullable platform hints, integrity fields, actual AV state und provider-opaque download_metadata mit relative resolve_endpoint und wahrheitsgemäßem range_supported-Wert.
  • Bei einem legacy artifact wird artifacts omitted, während artifact_ids bleibt; die API erfindet keine Metadaten und legt keine provider URL offen.
  • PR-F2.6.4 definiert bounded freshness: Ein Version-Write ist committed private/no-store, während anonymous catalog/version GET einen eventual shared cache nutzt; die cached PublicModVersion artifact expansion erfordert scan_status=clean, lifecycle=ready und publication state=published und bleibt eventual; direct Resolve-/Install-Plan-Reads sind private point-in-time reads über ein eligible target, dessen established state approved oder published sein kann. Current inventory enthält 53 approved public legacy targets und 4 published targets, daher ist direct eligibility nicht published-only und nicht legacy-only. Upload Status ist current database state at request time, Worker-Transitions sind eventual und progress.available=false bedeutet unknown; ein Install Plan ist ein deterministic private/no-store request-time snapshot; Webhooks sind feature-gated, eventual, at-least-once, replayable und unordered, mit no delivery promise while disabled. Numeric catalog convergence bleibt PR-F2.6.3, der live webhook rollout bleibt PR-F8.14.
Stable candidateAdditiv

Download-Integritätsgrenze

OpenAPI trennt jetzt den Stored-Object-SHA-256 von einem Transport-Representation-Validator, ohne ETag als content hash darzustellen.

  • sha256 und hashes.sha256 decken das vollständige immutable stored object ab; Clients vergleichen size_bytes, setzen alle Range-Teile zusammen und prüfen erst danach SHA-256.
  • ETag ist ein opaque non-cryptographic Validator für eine transport representation, keine file identity und kann sich zwischen primary, refreshed und fallback providers ändern.
  • Der aktuelle signed transport garantiert RFC 9530 Content-Digest oder Repr-Digest nicht; fail-closed OpenAPI lint lehnt falsche header- oder transcoding-claims ab.
Stable candidateAdditiv

Annahme eines asynchronen Upload-Abschlusses

Upload completion unterscheidet nun angenommene Hintergrundarbeit von einem bereits terminalen Ergebnis und behält dasselbe Response-DTO sowie idempotente Side Effects bei.

  • POST /v1/uploads/{upload_id}/complete liefert 202 Accepted für queued oder processing Jobs und verlangt Location exakt gleich data.job.statusEndpoint.
  • Ein terminales oder synchrones Ergebnis liefert 200 OK ohne Location; ein Replay mit dem ursprünglichen Idempotency-Key behält committed Status und Header bei, ohne Storage-, Audit- oder Webhook-Effekte zu wiederholen.
  • Der additive Status ist durch generated OpenAPI, curated Examples, Lint-Fehler und retained TypeScript-, Python- und C#-Client-Probes abgedeckt.
Beta toolingAdditiv

Official CLI und SDK compile gate

Die source distribution enthält jetzt eine official Node.js CLI für creator upload automation und ein explizites compile gate für jede generated SDK Sprache.

  • npm run api:cli bietet credential check, archive validation, upload create/resume/complete/status und einen vollständigen API-key-to-publish command, ohne secrets über argv anzunehmen.
  • Production, local sandbox und vom Operator bereitgestellte protected staging base URLs werden über environment profiles gewählt; staging nutzt MODDINGFLOW_STAGING_API_BASE_URL und einen separaten staging key.
  • npm run api:sdks:compile prüft einen echten TypeScript consumer, importiert das Python package ohne bytecode zu schreiben und baut den C# smoke consumer als Teil von npm run api:openapi:check.
Stable candidateAdditiv

Stable v1 OpenAPI documentation gate

OpenAPI 3.1 bleibt die Source of Truth für auth, scopes, errors, cursor pagination, upload sessions, download grants, webhooks, SDK source artifacts und public reference rendering.

  • Successful request/response examples decken install plan resolve, upload-session create/status/parts/complete/abort, download resolve/fallback und webhook subscription/delivery/redelivery flows ab.
  • Problem Details examples nutzen application/problem+json mit type, title, status, detail, instance, code, request_id und trace_id, damit Clients keine Prosa parsen.
  • Webhook verification guidance dokumentiert X-Moddingflow-Signature, X-Moddingflow-Timestamp, X-Moddingflow-Delivery-Id und HMAC-SHA256 über `${timestamp}.${raw_body}`.
Policy activeVeraltet

Compatibility, Deprecation und Sunset policy

Stable v1 old clients laufen im Support Window weiter, während additive changes über dokumentierte, tolerante OpenAPI-, SDK- und Docs-Updates ausgeliefert werden können.

  • Deprecated OpenAPI operations müssen x-deprecation-date, x-sunset-date, x-migration-url und x-changelog-url enthalten.
  • HTTP-visible deprecations nutzen Deprecation, Sunset und Link rel="deprecation" headers.
  • Minimum notice ist 90 days oder two stable API releases, je nachdem welches Fenster die sicherere Migration gibt.
  • Das Repository Release Gate verlangt vor Sunset committed migration evidence, einen bereiten non-deprecated replacement, dated telemetry review und einen approved support plan mit explizitem owner und approver.

Migration-Guide-Vorlagen

Jeder deprecation guide muss actionable sein: was ersetzt wird, wie affected clients gefunden werden, wie der replacement path ausgerollt wird und welche support evidence gebraucht wird.

Deprecated operation template

Deadline
Nicht vor x-sunset-date und mindestens 90 days oder two stable API releases nach x-deprecation-date.
Replacement
Replacement operationId/path, required scopes, request/response schema differences und expected Problem Details codes nennen.
Detection
Nach der deprecated operationId in SDK calls, OpenAPI client generation, logs, user-agent/client_id traffic und stored integration configs suchen.
Rollout
Replacement client path ergänzen, bei Bedarf dual-read oder dual-write aktivieren, idempotency/cursor behavior prüfen und die old operation nach sunset entfernen.
Support
X-Request-Id, request_id, trace_id, client_id, affected operationId und SDK version in support requests aufnehmen.

First stable v1 limitations

Deadline
Vor stable launch müssen limitations als release notes dokumentiert sein statt als hidden implementation details.
Replacement
Wenn eine capability noch beta oder experimental ist, x-moddingflow-stage=beta oder x-moddingflow-stage=experimental setzen und sie nicht zum prerequisite für stable flows machen.
Detection
Public OpenAPI paths, generated SDK clients, localized docs, FAQ und runtime route parity vor der Veröffentlichung vergleichen.
Rollout
Erst publizieren, wenn npm run api:openapi:check, npm run locales:validate und focused docs/reference rendering tests erfolgreich sind.
Support
Known limitations müssen auf changelog entry, migration guide oder support contact verweisen statt auf informelle Absprachen.

Release validation evidence

  • npm run api:openapi:generate -- --check bestätigt, dass committed JSON zum Rust generator passt.
  • npm run api:openapi:lint prueft examples, auth, scopes, Problem Details, pagination, uploads, downloads, webhooks und deprecation metadata.
  • npm run api:sdks:check bestätigt, dass generated TypeScript, Python und C# source artifacts zu OpenAPI operationIds und schemas passen.
  • npm run locales:validate hält API docs, reference, SDK, FAQ und changelog copy in ru, en und de synchron.