Release notes для совместимых v1 изменений, deprecation notices и migration guide шаблоны держатся рядом с OpenAPI, reference и SDK, чтобы клиенты видели не только endpoint, но и историю контракта.
Каждая совместимая public API поставка получает запись, где указаны affected operationIds, additive fields, docs examples и validation gates. Breaking removal требует новой major версии или завершенного deprecation path.
Классификация изменений
Каждая запись получает одну категорию совместимости, чтобы интеграторы отделяли обычные дополнения, миграции, новую major версию и действия по безопасности.
Additive
Совместимые optional fields или operations с синхронными OpenAPI, SDK, examples и tolerant-client evidence.
Deprecated
Старый flow сохраняется на период уведомления, пока опубликованы replacement, telemetry, migration guide и support guidance.
Breaking или new major
Несовместимое удаление или изменение смысла выпускается только в новой major версии либо после завершенного deprecation path.
Security
Security notes сообщают влияние и нужное действие клиента без опасных деталей. Небезопасная совместимость проходит emergency migration процесс.
База активна; сайт — release candidateAdditive
Настройки зашифрованного API-ключа аккаунта
Один компактный восстанавливаемый ключ аккаунта добавляет безопасную automation без записи Premium, ролей или лимитов в credential.
Ключ лениво создаётся при первом открытии, по умолчанию замаскирован, не истекает и проверяется через SHA-256 verifier; AES-256-GCM envelope обеспечивает повторный показ и скрытое копирование без хранения plaintext.
GET /me, GET /me/resources и PATCH /me/profile аддитивны и одинаковы в /v1 и /api/v1. GET /me раскрывает только safe metadata предъявленного credential, чтобы локальная automation могла проверить себя без доступа к credentials:manage. account:read, profile:write, builds:read и builds:write сгенерированы в OpenAPI и трёх SDK.
Ротация требует AAL2 и атомарно отзывает предшественника без overlap. Миграции 20260729091957, 20260729093738 и 20260729093915 применены; код сайта остаётся release candidate до deploy. Legacy hash-only ключ аккаунта требует явной ротации.
Account control plane additiveAdditive
Конфиденциальные OAuth-приложения аккаунта
Серверные и локальные интеграции могут создать и перевыпустить защищённый OAuth client secret в настройках без изменения secretless public PKCE clients.
Настройки > Для разработчиков > OAuth-приложения создаёт opaque client_id и после AAL2/2FA step-up один раз показывает замаскированный mfoc_ client_secret; Supabase хранит только SHA-256 verifier и безопасный display prefix.
Confidential applications используют client_secret_basic с Device Flow и refresh token для базовых scopes. Ротация сразу заменяет secret, отзывает refresh families и pending grants, а уже выданные access tokens истекают не позднее чем через 15 минут.
Удаление отключает приложение и отзывает его grants. Distributed desktop, mobile, CLI и Mod Manager остаются public clients и продолжают использовать Dynamic Client Registration с PKCE без secret.
Stable v1 additiveAdditive
Версии отдельных файлов модов
Каждый artifact и файл install plan теперь сообщает собственную версию без удаления полей совместимости.
PublicModArtifact.file_version и InstallPlanStep.file.file_version добавлены как optional поля OpenAPI для совместимости со старыми клиентами; актуальные ответы заполняют их версией выбранного файла.
PublicModVersion.version равна file_version раскрытого artifact, а PublicMod.latest_version и latest_release.version вычисляются из первого активного основного файла.
Моды больше не имеют отдельно редактируемой общей версии: каждый основной и заполненный опциональный файл получает обязательную строку версии длиной до 80 символов.
Stable v1 additiveAdditive
Полные метаданные PublicMod
Каталог и download resolve возвращают один авторитетный снимок мода с полным Markdown, uploader, постоянными ссылками и точными данными актуального релиза.
GET /v1/mods и GET /v1/mods/{mod_id} сохраняют summary как короткий excerpt, а description отдают как неусечённый Markdown первого видимого сообщения; description_format равен markdown.
author содержит только uploader Moddingflow; profile_url равен null для закрытого профиля. homepage_url остаётся сайтом автора или проекта, source_url — указанной автором исходной страницей, а links.web/api/versions — абсолютными постоянными ссылками Moddingflow.
latest_version сохранён; latest_release добавляет authoritative version/artifact IDs и отдельные published_at/updated_at. POST /v1/downloads/{artifact_id}/resolve возвращает тот же PublicMod, точную выбранную version и artifact, distribution и временный primary_url с expires_at и стабильным resolve endpoint для обновления ссылки.
Stable candidateAdditive
SLO, freshness и capacity budgets
Public API получил числовые product SLO, strong If-Match для mutable writes и admission budgets до provider signing.
Цели: availability ≥99.9%, latency p95 ≤2000 ms, catalog p95 ≤15 s, search index p95 ≤1800 s, RPO ≤24 h и RTO ≤4 h; warning/critical alerts срабатывают до breach.
Mod и ModVersion PATCH требуют strong If-Match и возвращают новый ETag. Missing validator даёт 428, malformed/weak/wildcard/list — 412 без mutation, а корректный stale — 412 с текущим ETag; старые SDK сохраняют Problem Details и status.
Multipart default изменён на 16 MiB × 4 после live R2 capacity probe. Primary и fallback download admission проверяют authoritative size, actor/client concurrency и byte buckets до дорогого signing; leases восстанавливаются после failure или expiry.
Stable candidateAdditive
Универсальные domain ID и lifecycle
Все 13 публичных сущностей получили единые opaque UUID, ownership/state rules, tombstone/410 non-reuse и immutable snapshot опубликованной версии без удаления legacy aliases.
Game, Mod, ModVersion, Artifact, Blob, UploadSession, DownloadGrant, User, Team, Dependency, Job, WebhookSubscription и WebhookDelivery имеют отдельные UUID и fail-closed state machines. Rename сохраняет ID; slug, filename, URL, storage key, ETag и hash не являются identity.
Archive можно восстановить, permanent delete оставляет retained tombstone и возвращает 410. UUID и source binding никогда не переиспользуются; неизвестный ID возвращает 404.
Первая публикация фиксирует canonical snapshot и SHA-256. Semantic fields immutable; restore требует точного snapshot и текущих upload-trust gates. lifecycle_version защищает concurrent updates. Старые uploaded/quarantined/approved/rejected values остаются compatibility aliases.
Stable candidateAdditive
Fail-closed compensation boundaries
PR-F2.6.6 и PR-F2.6.7 фиксируют replay и recovery для контрольных точек provider upload commit, ready binding, publish/outbox и trust enqueue без ослабления trust или publication preconditions.
Cross-provider transaction не заявляется. Once-only generation byte-budget checkpoint предшествует atomic session/file/upload.accepted reservation; replay между ними использует тот же budget result. Каждый single PUT возвращает signed If-None-Match: * и максимум 900-second URL lease, row-lock checkpointed после sign и до response; abort-winning checkpoint отклоняет URL. Conditional 412 ведёт в complete для authoritative HEAD/seal/SHA-256. Затем session-level claim условно копирует точный client-source ETag в write-once server-only seal до queued scan checkpoint.
Heartbeat-backed claim token ограждает каждую scan mutation. Ready, quarantine и rejection атомарно фиксируют session/file/job state, audit и canonical event; terminal replay точно перечитывает и проверяет этот envelope. Перед provider config и normal claim bounded DB-only sweep восстанавливает stale max-attempt claim без повторного scan/provider work: coherent state атомарно получает canonical manual review/quarantine, а incoherent state terminal-fail-ит только exact job для видимого manual intervention. Same-SHA final promotion использует durable SHA/bucket/key claim, canonical MIME и cf-copy-destination-if-none-match: *; fresh duplicate ждёт или принимает ready blob без расхода normal scan attempt. Polling экспоненциальный и ограничен 15 минутами на claim. Первые два durable token-fenced yield атомарно восстанавливают normal attempt и requeue-ят job с DB-owned jitter 30–60 секунд; третий атомарно создаёт manual review/quarantine с exact lost-response replay вместо бесконечного retry. Lost copy response требует exact HEAD и nonblank ETag. Content-addressed final copy становится ready только после accessible attested blob и atomic ready/audit/file.ready binding. Transactional publish и durable outbox тоже используют одну transaction. Quarantine scan.completed и последующее file.ready сохраняют разные идентификаторы. Account-inbox notification не является lifecycle acknowledgement.
После lost response same Idempotency-Key повторно получает только тот же generation claim и сходится без дублирования budget, audit, job, terminal-event или outbox effects. Для single cleanup durable stage 1 условно пишет zero-byte tombstone и проверяет provider ETag, LastModified, metadata token и size=0; fence удерживается до latest URL lease и минимум 16 минут. Stage 2 exact-delete/HEAD-проверяет staging и завершает DB; crash replay продолжает stage. Multipart cleanup abort-ит и relist-ит exact-key uploads, каждый seal claim key удаляется и проверяется, quarantine сохраняется. Desired CORS включает If-None-Match, object-level probe подтверждает conditional copy и late-PUT tombstone rejection, но live CORS/lifecycle/lock evidence остаётся BLOCKED до CLOUDFLARE_API_TOKEN, MODDINGFLOW_R2_FINAL_LOCK_MIN_SECONDS и MODDINGFLOW_R2_ALLOWED_BROWSER_ORIGINS; live deployment не заявляется. Unbound final copy remains non-ready и never publishable до PR-F3.13 reference-aware legal-hold-safe deletion. Numeric freshness остаётся PR-F2.6.3, deployed webhook enablement — PR-F8.14.
Stable candidateAdditive
Managed artifact expansion
Optional PublicModVersion.artifacts добавляет complete metadata для managed primary artifact, сохраняя artifact_ids как стабильную v1 связь.
Expansion доступен только при size_bytes > 0, точном sha256/hashes.sha256, current upload-session match по file_id и final_blob_id, actual AV scan_status=clean, lifecycle=ready, publication state=published и managed resolve eligibility.
Полный artifact содержит role/category, display и nullable platform hints, integrity fields, actual AV state и provider-opaque download_metadata с relative resolve_endpoint и truthful range_supported.
Для legacy artifact поле artifacts будет omitted, а artifact_ids сохранится; API не фабрикует metadata и не раскрывает provider URL.
PR-F2.6.4 фиксирует bounded freshness: version write — committed private/no-store, anonymous catalog/version GET — eventual shared cache; cached PublicModVersion artifact expansion требует scan_status=clean, lifecycle=ready и publication state=published и остаётся eventual; direct resolve/install plan — private point-in-time reads по eligible target, чьё established state может быть approved или published. Current inventory содержит 53 approved public legacy targets и 4 published targets, поэтому direct eligibility не является published-only или legacy-only. Upload status показывает current DB state at request, worker transitions eventual, progress.available=false означает unknown; install plan — deterministic private/no-store request-time snapshot; webhooks feature-gated, eventual, at-least-once, replayable и unordered, с no delivery promise while disabled. Numeric catalog convergence остаётся PR-F2.6.3, live webhook rollout — PR-F8.14.
Stable candidateAdditive
Граница целостности download
OpenAPI теперь машинно различает stored-object SHA-256 и transport representation validator, не выдавая ETag за content hash.
sha256 и hashes.sha256 покрывают полный immutable stored object; клиент сначала сверяет size_bytes, собирает все Range части и только затем проверяет SHA-256.
ETag является opaque non-cryptographic validator одной transport representation, не служит file identity и может измениться между primary, refreshed и fallback providers.
RFC 9530 Content-Digest и Repr-Digest текущим signed transport не гарантируются; fail-closed OpenAPI lint запрещает ложные header или transcoding claims.
Stable candidateAdditive
Принятие асинхронного завершения upload
Upload completion теперь отличает принятую фоновую работу от уже terminal результата, сохраняя тот же response DTO и идемпотентные side effects.
POST /v1/uploads/{upload_id}/complete возвращает 202 Accepted для queued или processing job и требует, чтобы Location в точности совпадал с data.job.statusEndpoint.
Terminal или synchronous результат возвращает 200 OK без Location; replay с исходным Idempotency-Key сохраняет committed status/header без повторения storage, audit или webhook effects.
Additive status покрыт generated OpenAPI, curated examples, lint failures и retained TypeScript, Python и C# client probes.
Beta toolingAdditive
Official CLI и SDK compile gate
Source distribution теперь включает official Node.js CLI для creator upload automation и отдельный compile gate для каждого языка generated SDK.
npm run api:cli дает credential check, archive validation, upload create/resume/complete/status и полный API-key-to-publish command, не принимая secrets через argv.
Production, local sandbox и выданные оператором protected staging base URLs выбираются через environment profiles; staging использует MODDINGFLOW_STAGING_API_BASE_URL и отдельный staging key.
npm run api:sdks:compile проверяет реальный TypeScript consumer, импортирует Python package без записи bytecode и собирает C# smoke consumer внутри npm run api:openapi:check.
Stable candidateAdditive
Stable v1 OpenAPI documentation gate
OpenAPI 3.1 остается источником правды для auth, scopes, errors, cursor pagination, upload sessions, download grants, webhooks, SDK source artifacts и public reference rendering.
Successful request/response examples cover install plan resolve, upload-session create/status/parts/complete/abort, download resolve/fallback and webhook subscription/delivery/redelivery flows.
Problem Details examples use application/problem+json with type, title, status, detail, instance, code, request_id and trace_id so clients do not parse prose.
Webhook verification guidance documents X-Moddingflow-Signature, X-Moddingflow-Timestamp, X-Moddingflow-Delivery-Id and HMAC-SHA256 over `${timestamp}.${raw_body}`.
Policy activeDeprecated
Compatibility, Deprecation and Sunset policy
Stable v1 old clients keep working during the support window while additive changes can ship through documented, tolerant OpenAPI/SDK/docs updates.
Deprecated OpenAPI operations must include x-deprecation-date, x-sunset-date, x-migration-url and x-changelog-url.
HTTP-visible deprecations use Deprecation, Sunset and Link rel="deprecation" headers.
Minimum notice is 90 days or two stable API releases, whichever gives the safer migration window.
Repository release gate требует committed migration evidence, готовый non-deprecated replacement, dated telemetry review и approved support plan с явными owner и approver до Sunset.
Migration guide templates
Каждый deprecation guide должен быть actionable: что заменить, как найти affected clients, как раскатить замену и куда отправить support evidence.
Deprecated operation template
Deadline
Не раньше x-sunset-date и минимум через 90 days или two stable API releases после x-deprecation-date.
Replacement
Указать replacement operationId/path, required scopes, request/response schema differences и expected Problem Details codes.
Detection
Искать deprecated operationId в SDK calls, OpenAPI client generation, logs, user-agent/client_id traffic и stored integration configs.
Rollout
Добавить replacement client path, включить dual-read или dual-write если нужно, проверить idempotency/cursor behavior, затем удалить old operation после sunset.
Support
Передавать X-Request-Id, request_id, trace_id, client_id, affected operationId и SDK version в support request.
First stable v1 limitations
Deadline
До stable launch ограничения должны быть описаны как release notes, а не hidden implementation details.
Replacement
Если capability еще beta/experimental, пометить x-moddingflow-stage=beta или x-moddingflow-stage=experimental и не делать ее prerequisite для stable flows.
Detection
Сравнить public OpenAPI paths, SDK generated clients, localized docs, FAQ и runtime route parity перед публикацией.
Rollout
Публиковать только после npm run api:openapi:check, npm run locales:validate и focused docs/reference rendering tests.
Support
Known limitations должны ссылаться на changelog entry, migration guide или support contact вместо устной договоренности.
Release validation evidence
npm run api:openapi:generate -- --check confirms committed JSON matches the Rust generator.
npm run api:openapi:lint checks examples, auth, scopes, Problem Details, pagination, uploads, downloads, webhooks and deprecation metadata.
npm run api:sdks:check confirms generated TypeScript, Python and C# source artifacts match OpenAPI operationIds and schemas.
npm run locales:validate keeps API docs, reference, SDK, FAQ and changelog copy synchronized across ru, en and de.