diff --git a/rules/patterns/go-database/contract.md b/rules/patterns/go-database/contract.md index 5cc0734..1a929eb 100644 --- a/rules/patterns/go-database/contract.md +++ b/rules/patterns/go-database/contract.md @@ -1,6 +1,6 @@ # Contract: Database Patterns (Go / MySQL / MariaDB) -Version: 1.6 +Version: 1.7 ## MySQL Transaction Cursor Safety (CRITICAL) @@ -127,6 +127,7 @@ Rules: ## Migration Policy +- For local-first desktop applications, startup and migration recovery must follow the `local-first-recovery` contract. - Migrations are numbered sequentially and never modified after merge. - Trigger, take, and verify a fresh backup through the application-owned backup mechanism before applying migrations to any non-ephemeral database. - Each migration must be reversible where possible (document rollback in a comment). diff --git a/rules/patterns/local-first-recovery/contract.md b/rules/patterns/local-first-recovery/contract.md new file mode 100644 index 0000000..1fefc7e --- /dev/null +++ b/rules/patterns/local-first-recovery/contract.md @@ -0,0 +1,95 @@ +# Contract: Local-First Recovery + +Version: 1.1 + +## Purpose + +Shared recovery and migration rules for local-first desktop applications that keep local state and may rebuild part of that state from sync, reload, import, or other deterministic upstream sources. + +## Core Rule + +A migration or startup strategy is not considered sufficient merely because it succeeded once on the current developer database. + +Priority order: +- Priority 1: protect user data. Do not do anything that can damage, discard, or silently rewrite non-recoverable user data. +- Priority 2: preserve availability. Do not do anything that unnecessarily prevents the application from starting or operating in a reduced mode. + +If user data is safe, prefer degraded startup over startup failure. If minimum useful functionality can be started safely, start it. + +Startup and schema-migration behavior must be designed for degraded real-world states, including: +- legacy schema versions +- interrupted migrations +- stale temp tables +- invalid payloads +- duplicates +- `NULL` in required columns +- partially migrated tables + +## Required Data Classification + +The architecture must explicitly separate: +- disposable cache tables +- protected user data tables + +Definitions: +- Disposable cache tables are read-only, sync-derived, imported, or otherwise rebuildable from a trusted source. +- Protected user data tables contain user-authored or otherwise non-rebuildable data. + +Do not mix both classes in one table if recovery semantics differ. + +## Availability Policy For Disposable Data + +For disposable cache tables, availability has priority. + +Rules: +- If a table cannot be migrated safely, it may be quarantined, dropped, or recreated empty. +- The application must continue startup after such recovery. +- The application must restore disposable data through the normal sync, reload, import, or rebuild path. +- Recovery must not require manual SQL intervention for routine degraded states. + +## Protection Policy For User Data + +For protected user data, destructive reset is forbidden. + +Rules: +- Do not drop, truncate, or recreate protected tables as a recovery shortcut. +- Backup-before-change is mandatory and must follow the `backup-management` contract. +- Validate-before-migrate is mandatory. +- Migration logic must use fail-safe semantics: stop before applying a risky destructive step when invariants are broken or input is invalid. +- The application must emit explicit diagnostics that identify the blocked table, migration step, and reason. + +## Recovery Logic Requirements + +Rules: +- Recovery logic must be deterministic. +- Recovery logic must be idempotent. +- Recovery logic must be retry-safe on every startup. +- Recovery logic must be observable through structured logs. +- Re-running startup after a partial failure must move the system toward a valid state, not deeper into corruption. + +## Quality Bar + +The application must either: +- self-recover and continue startup + +or: + +- stop only when continuing would risk loss or corruption of non-recoverable user data + +Stopping for disposable cache corruption alone is not acceptable when the data can be rebuilt safely. + +If the full feature set cannot be restored safely during startup, the application should start with the minimum safe functionality instead of failing startup, as long as protected user data remains safe. + +## Testing Requirements + +Degraded and legacy states must be tested explicitly, not only happy-path fresh installs. + +Required test coverage includes: +- legacy schema upgrades +- interrupted migration recovery +- partially migrated tables +- duplicate rows where uniqueness is expected +- `NULL` in required columns +- invalid payloads in persisted rows +- disposable-table reset and rebuild flow +- protected-data migration refusal with explicit diagnostics diff --git a/rules/patterns/testing-policy/contract.md b/rules/patterns/testing-policy/contract.md index c84dd89..c837c7f 100644 --- a/rules/patterns/testing-policy/contract.md +++ b/rules/patterns/testing-policy/contract.md @@ -1,6 +1,6 @@ # Contract: Testing Policy -Version: 1.0 +Version: 1.1 ## Purpose @@ -17,10 +17,13 @@ Version: 1.0 - **Трансформации** — конвертация единиц, нормализация, маппинг полей - **Бизнес-правила** — расчёты, фильтрация, агрегация, приоритизация - **Граничные случаи** — пустой ввод, нулевые значения, переполнение, отсутствующие поля +- **Degraded / legacy states** — legacy schema, interrupted migrations, duplicates, invalid persisted rows, partially migrated tables - **Регрессии** — если баг был найден, тест фиксирует его до исправления Тест пишется в том же коммите, что и функциональность. Функциональность без теста (там где он обязателен) — неполный коммит. +Для local-first desktop приложений правила деградированных состояний и recovery-тестов определяются также `local-first-recovery` contract. + --- ## Когда тест не нужен