Duet v0.1.0-alpha.5
Alpha 5 gives Duet its own durable SD-card namespace without abandoning the history already stored by CrossInk and CrossPoint.
Firmware
- Xteink X3:
Duet-X3-v0.1.0-alpha.5.bin - Xteink X4:
Duet-X4-v0.1.0-alpha.5.bin
Canonical Storage
All new Duet-owned writes now live beneath:
/.duet/
├── state/ settings, stats, achievements, sync, catalogs
├── books/ durable per-book progress and reader settings
├── cache/
│ ├── thumbs/ exact-size grid and carousel covers
│ ├── layouts/ disposable chapter/page layouts
│ └── fileindex/ SD file-index cache
├── backups/
│ └── reading-stats/
└── migration/
└── legacy-import-v1.complete
The layout and every legacy mapping are centralized in lib/DuetStorage/; individual features do not invent their own root paths.
Non-Destructive Compatibility
/.crossinkis the newer legacy global-state and thumbnail source./.crosspointis the older global and per-book source./.crossink-stats-backupremains a reading-stats backup source.- Existing canonical files always win. The importer never replaces them with older state.
- Bounded global files import on first boot. Large per-book state moves lazily when the corresponding book is opened, avoiding a thousands-entry boot scan.
- Copies use a temporary destination, flush and size verification, and atomic rename. The completion marker is written only when the bounded import has no failures.
- An interrupted migration retries on the next boot. Reads continue falling back to untouched legacy files until canonical copies are available.
- Legacy directories are never deleted automatically. Cleanup is a separate, explicit user decision after physical verification.
- Existing cache identity remains stable, preserving current-book selection, library statistics, KOReader position matching, and Nearby Reading Stats Sync records.
Desktop Tools
Cover prefill now writes exact-size thumbnails to /.duet/cache/thumbs and its report to /.duet/state/desktop_cover_prefill.json. Existing valid legacy thumbnails are copied into the canonical cache by default; --force still means regenerate, and legacy cleanup still requires the explicit --cleanup-legacy-thumbnails option.
Library-index generation, simulator fixtures, and release packaging use the same centralized Python path definitions.
Verification
- The complete native suite passes: 117/117 tests.
- Focused migration coverage passes 9/9 scenarios: fresh cards, either legacy tree, both trees, partial migration, existing canonical state, interrupted retry, completed reboot, and stable per-book identity.
- The X3 and X4 simulator builds and scripted smoke routes pass against this exact source state, including Home, library, reader, More Info, sleep, relayout, and progress reload.
- Both hardware targets compile as distinct Alpha 5 artifacts:
| Device | Artifact | SHA-256 |
|---|---|---|
| X3 | .pio/build/tiny/Duet-X3-v0.1.0-alpha.5.bin | 5d20c9e8f33088e2ce15c0f8f66468a66bcbd5754b920442fcf38bfa72965904 |
| X4 | .pio/build/xlarge/Duet-X4-v0.1.0-alpha.5.bin | 37fb33fd4b02d473e8c9056977c19dbc19aafbc0953926523c64db9d9cf6e4e8 |
- X3 static RAM use is 105,084 of 327,680 bytes (32.1%); its firmware image is 5,599,408 bytes with 954,192 bytes of OTA space remaining.
- X4 static RAM use is 105,020 of 327,680 bytes (32.0%); its firmware image is 5,462,336 bytes with 1,091,264 bytes of OTA space remaining.
- Python release tooling compiles cleanly.
- No SD card was staged or flashed while preparing this candidate.
Build and native-test success are not physical acceptance. Keep the previous known-good BIN and a complete card backup. Physical X3 and X4 checks must still confirm first boot, second boot, active book, progress, settings, statistics, achievements, covers, catalogs, both sync paths, book open/close, sleep, and wake.