|
| 1 | +<!-- SPDX-License-Identifier: MIT --> |
| 2 | +<!-- Part of PyBLE (https://pyble.dev) — see /LICENSE. --> |
| 3 | + |
| 4 | +# ADR 0048 — Recover one current text draft through the planned Drift store |
| 5 | + |
| 6 | +**Status:** Specified for implementation (2026-09-25) under the user's request |
| 7 | +to execute C1-S1. Source implementation and physical acceptance remain pending; no named human |
| 8 | +sign-off is claimed and this is not release admission. |
| 9 | + |
| 10 | +## Context |
| 11 | + |
| 12 | +[ADR-0010](0010-working-loop-in-memory-document.md) recorded an intentionally |
| 13 | +volatile current document and deferred Drift persistence to A-24. That |
| 14 | +limitation remains in the inspected source. Its old rich-editor deferral has |
| 15 | +already been superseded by [ADR-0012](0012-flutter-code-editor-behind-editorsurface.md), |
| 16 | +so the persistence problem must be scoped against the current rich Editor, |
| 17 | +Blocks handoff and file-backed Run implementation. |
| 18 | + |
| 19 | +The current provider has a mutation epoch, but Save/Run/Files completion guards |
| 20 | +still compare document values. A stable Connection facade also makes object |
| 21 | +identity insufficient to bind a multi-step text action to one attached board. |
| 22 | +Recovery must not amplify either gap by restoring a historical target as |
| 23 | +current write authority. |
| 24 | + |
| 25 | +C1-S1 requests a bounded contract and an honest estimate, not the full A-24 |
| 26 | +implementation. The [design review and sizing](../developments/2026-q4-reliable-workflow/c1-s1/03_Recovery_Design_and_Sizing.md) |
| 27 | +records this distinction and the proposed reforecast. |
| 28 | + |
| 29 | +## Decision |
| 30 | + |
| 31 | +Adopt [the bounded current-draft contract](../specifications/App/current-draft-recovery.md) |
| 32 | +for the next implementation slice: |
| 33 | + |
| 34 | +1. Use one current-text slot in the planned Drift `projects`/`project_files` |
| 35 | + subset and single SettingsStore. Commit its content and recovery metadata |
| 36 | + atomically. No scratch file or separate preferences backend. |
| 37 | +2. Distinguish local checkpoint state from board-dirty state. A saved-local |
| 38 | + indication acknowledges a successful transaction for that exact revision. |
| 39 | +3. Offer explicit offline Restore/Discard with nondestructive failure handling. |
| 40 | + A local recovery panel is a narrow extension of |
| 41 | + [ADR-0011](0011-connection-gated-shell.md); it does not implement the complete |
| 42 | + offline IDE. |
| 43 | +4. Restore text without board authority. Require a current-session destination |
| 44 | + decision before a recovered document can be saved, uploaded or run on a |
| 45 | + board; use document epochs and the existing neutral session stamp across |
| 46 | + asynchronous boundaries. |
| 47 | +5. Include interrupted-write, corrupt/full storage, version handling, stale |
| 48 | + completions and applicable platform evidence in the same usable increment. |
| 49 | + Keep Blocks graph recovery and the rest of A-24 explicitly carried. |
| 50 | + |
| 51 | +This decision supersedes only ADR-0010's volatile-only current-text design for |
| 52 | +the future accepted slice. It does not retroactively claim that released builds |
| 53 | +persist drafts, change PBLE/1 or remove the existing provider/Connection seams. |
| 54 | + |
| 55 | +## Alternatives considered |
| 56 | + |
| 57 | +| Option | Decision | |
| 58 | +|---|---| |
| 59 | +| Ad-hoc text/JSON scratch file or separate preferences | Rejected: duplicates the accepted Drift direction and leaves another migration/storage boundary | |
| 60 | +| Complete all A-24 projects, histories, imports and Blocks state together | Deferred: exceeds the first bounded outcome and needs separate contracts | |
| 61 | +| Infer the old board from a recovered path or advertised name | Rejected: path and display identity do not authorize a new session | |
| 62 | +| Restore automatically over a fresh empty provider | Rejected: races hydration, user edits and pending replacement decisions | |
| 63 | +| Ship only successful restart recovery, add failure handling later | Rejected: cannot meet the recovery story's minimum safety acceptance | |
| 64 | + |
| 65 | +## Consequences |
| 66 | + |
| 67 | +The implementation needs the actual Drift/native database dependencies, |
| 68 | +versioned schemas, local recovery UI and stronger completion guards. None of |
| 69 | +these exist merely because this ADR is written. The estimate exceeds the |
| 70 | +original C1-S2 recovery allowance; future Sprint selection must be reforecast |
| 71 | +without weakening the failure cases. The narrower feature can eventually |
| 72 | +protect useful current text, while full project persistence remains unfinished. |
0 commit comments