M9 + all boards: persist the companion app-sync ring across power cycles

User report: the M9 "does not remember chats or sync them to the app" while
the V4-R8 does. The companion sync ring (MyMesh::history_ring + per-client
cursors) was RAM-only on every board — invisible on a USB-powered V4 that
rarely loses power, fatal on the M9 whose only off is the hard-cut slider.

Shared fix: the ring is now an append log (/synchist) plus client cursors
(/synccur) on DataStore::getHotDataFS(), restored in MyMesh::begin() and
flushed by persistSyncHistoryNow() on the paths that lose RAM (deep sleep,
power-off, explicit save). Record + bench-test recipe: M9_PORT.md Deferred #13.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Christopher Van HooseandClaude Fable 5 committed 2026-08-20 13:50:48 -04:00
1 parent c9251aec61
commit 16e883187c
6 files changed
+346 -2

No files matched your search

+23
View File
@@ -216,6 +216,29 @@ bool DataStore::removeFile(FILESYSTEM* fs, const char* filename) {
return fs->remove(filename);
}
#if defined(ESP32)
File DataStore::openAppend(FILESYSTEM* fs, const char* filename) {
return fs->open(_rp(filename), "a", true);
}
bool DataStore::fileExists(FILESYSTEM* fs, const char* filename) {
return fs->exists(_rp(filename));
}
bool DataStore::removeRooted(FILESYSTEM* fs, const char* filename) {
return fs->remove(_rp(filename));
}
bool DataStore::renameFile(FILESYSTEM* fs, const char* from, const char* to) {
// _rp() hands back ONE shared scratch buffer, so the two paths must be built
// into independent buffers (same trap savePrefs documents).
char from_path[80], to_path[80];
snprintf(from_path, sizeof(from_path), "%s%s", _root, from);
snprintf(to_path, sizeof(to_path), "%s%s", _root, to);
return fs->rename(from_path, to_path);
}
#endif
bool DataStore::formatFileSystem() {
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
if (_fsExtra == nullptr) {