diff --git a/lib/reducers/entry-reducer.js b/lib/reducers/entry-reducer.js
--- a/lib/reducers/entry-reducer.js
+++ b/lib/reducers/entry-reducer.js
@@ -40,6 +40,7 @@
   legacyLogInActionTypes,
 } from '../actions/user-actions.js';
 import { setNewSessionActionType } from '../keyserver-conn/keyserver-conn-types.js';
+import type { EntryStoreOperation } from '../ops/entries-store-ops.js';
 import { entryID } from '../shared/entry-utils.js';
 import { stateSyncSpecs } from '../shared/state-sync/state-sync-specs.js';
 import { threadInFilterList } from '../shared/thread-utils.js';
@@ -166,7 +167,11 @@
   entryStore: EntryStore,
   action: BaseAction,
   newThreadInfos: RawThreadInfos,
-): [EntryStore, $ReadOnlyArray<ClientEntryInconsistencyReportCreationRequest>] {
+): {
+  +entryStore: EntryStore,
+  +entryStoreOperations: $ReadOnlyArray<EntryStoreOperation>,
+  +reportCreationRequests: $ReadOnlyArray<ClientEntryInconsistencyReportCreationRequest>,
+} {
   const { entryInfos, daysToEntries, lastUserInteractionCalendar } = entryStore;
   if (
     action.type === deleteKeyserverAccountActionTypes.success ||
@@ -179,27 +184,29 @@
     )(entryInfos);
 
     if (Object.keys(newEntryInfos).length === Object.keys(entryInfos).length) {
-      return [
-        {
+      return {
+        entryStore: {
           entryInfos,
           daysToEntries,
           lastUserInteractionCalendar,
         },
-        [],
-      ];
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
     const newDaysToEntries = filterExistingDaysToEntriesWithNewEntryInfos(
       daysToEntries,
       newEntryInfos,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries: newDaysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === setNewSessionActionType) {
     const authorizedThreadInfos = _pickBy(threadInFilterList)(newThreadInfos);
     const newEntryInfos = _pickBy(
@@ -219,23 +226,25 @@
     }
 
     if (Object.keys(newEntryInfos).length === Object.keys(entryInfos).length) {
-      return [
-        {
+      return {
+        entryStore: {
           entryInfos,
           daysToEntries,
           lastUserInteractionCalendar: newLastUserInteractionCalendar,
         },
-        [],
-      ];
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries: newDaysToEntries,
         lastUserInteractionCalendar: newLastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === fetchEntriesActionTypes.success) {
     const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos(
       entryInfos,
@@ -243,27 +252,29 @@
       action.payload.rawEntryInfos,
       newThreadInfos,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: updatedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (
     action.type === updateCalendarQueryActionTypes.started &&
     action.payload &&
     action.payload.calendarQuery
   ) {
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos,
         daysToEntries,
         lastUserInteractionCalendar: Date.now(),
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === updateCalendarQueryActionTypes.success) {
     const newLastUserInteractionCalendar = action.payload.calendarQuery
       ? Date.now()
@@ -278,14 +289,15 @@
       updatedEntryInfos,
       action.payload.deletedEntryIDs,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: deletionMarkedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar: newLastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === createLocalEntryActionType) {
     const entryInfo = action.payload;
     const localID = entryInfo.localID;
@@ -303,14 +315,15 @@
       ...daysToEntries,
       [dayString]: _union([localID])(daysToEntries[dayString]),
     };
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries: newDaysToEntries,
         lastUserInteractionCalendar: Date.now(),
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === createEntryActionTypes.success) {
     const localID = action.payload.localID;
     const serverID = action.payload.entryID;
@@ -331,7 +344,11 @@
       )(entryInfos);
     } else {
       // This happens if the entry is deauthorized before it's saved
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
 
     const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos(
@@ -340,15 +357,15 @@
       mergeUpdateEntryInfos([], action.payload.updatesResult.viewerUpdates),
       newThreadInfos,
     );
-
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: updatedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar: Date.now(),
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === saveEntryActionTypes.success) {
     const serverID = action.payload.entryID;
     if (
@@ -356,7 +373,11 @@
       !threadInFilterList(newThreadInfos[entryInfos[serverID].threadID])
     ) {
       // This happens if the entry is deauthorized before it's saved
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
 
     const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos(
@@ -366,14 +387,15 @@
       newThreadInfos,
     );
 
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: updatedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar: Date.now(),
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === concurrentModificationResetActionType) {
     const { payload } = action;
     if (
@@ -381,7 +403,11 @@
       !threadInFilterList(newThreadInfos[entryInfos[payload.id].threadID])
     ) {
       // This happens if the entry is deauthorized before it's restored
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
     const newEntryInfos = {
       ...entryInfos,
@@ -390,14 +416,15 @@
         text: payload.dbText,
       },
     };
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === deleteEntryActionTypes.started) {
     const payload = action.payload;
     const id =
@@ -412,14 +439,15 @@
         deleted: true,
       },
     };
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries,
         lastUserInteractionCalendar: Date.now(),
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === deleteEntryActionTypes.success) {
     const { payload } = action;
     if (payload) {
@@ -429,14 +457,15 @@
         mergeUpdateEntryInfos([], payload.updatesResult.viewerUpdates),
         newThreadInfos,
       );
-      return [
-        {
+      return {
+        entryStore: {
           entryInfos: updatedEntryInfos,
           daysToEntries: updatedDaysToEntries,
           lastUserInteractionCalendar,
         },
-        [],
-      ];
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
   } else if (action.type === fetchRevisionsForEntryActionTypes.success) {
     const id = action.payload.entryID;
@@ -445,7 +474,11 @@
       !threadInFilterList(newThreadInfos[entryInfos[id].threadID])
     ) {
       // This happens if the entry is deauthorized before it's restored
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
     // Make sure the entry is in sync with its latest revision
     const newEntryInfos = {
@@ -456,14 +489,15 @@
         deleted: action.payload.deleted,
       },
     };
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === restoreEntryActionTypes.success) {
     const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos(
       entryInfos,
@@ -471,14 +505,15 @@
       mergeUpdateEntryInfos([], action.payload.updatesResult.viewerUpdates),
       newThreadInfos,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: updatedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar: Date.now(),
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (
     action.type === legacyLogInActionTypes.success ||
     action.type === legacySiweAuthActionTypes.success ||
@@ -492,14 +527,15 @@
         calendarResult.rawEntryInfos,
         newThreadInfos,
       );
-      return [
-        {
+      return {
+        entryStore: {
           entryInfos: updatedEntryInfos,
           daysToEntries: updatedDaysToEntries,
           lastUserInteractionCalendar,
         },
-        [],
-      ];
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
   } else if (action.type === incrementalStateSyncActionType) {
     const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos(
@@ -515,14 +551,15 @@
       updatedEntryInfos,
       action.payload.deletedEntryIDs,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: deletionMarkedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (
     action.type === processUpdatesActionType ||
     action.type === joinThreadActionTypes.success ||
@@ -534,14 +571,15 @@
       mergeUpdateEntryInfos([], action.payload.updatesResult.newUpdates),
       newThreadInfos,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: updatedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === fullStateSyncActionType) {
     const [updatedEntryInfos, updatedDaysToEntries] = mergeNewEntryInfos(
       entryInfos,
@@ -549,14 +587,15 @@
       action.payload.rawEntryInfos,
       newThreadInfos,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: updatedEntryInfos,
         daysToEntries: updatedDaysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (
     action.type === changeThreadSettingsActionTypes.success ||
     action.type === removeUsersFromThreadActionTypes.success ||
@@ -567,30 +606,43 @@
       (entry: RawEntryInfo) => authorizedThreadInfos[entry.threadID],
     )(entryInfos);
     if (Object.keys(newEntryInfos).length === Object.keys(entryInfos).length) {
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
     const newDaysToEntries = filterExistingDaysToEntriesWithNewEntryInfos(
       daysToEntries,
       newEntryInfos,
     );
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: newEntryInfos,
         daysToEntries: newDaysToEntries,
         lastUserInteractionCalendar,
       },
-      [],
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: [],
+    };
   } else if (action.type === processServerRequestsActionType) {
     const checkStateRequest = action.payload.serverRequests.find(
       candidate => candidate.type === serverRequestTypes.CHECK_STATE,
     );
     if (!checkStateRequest || !checkStateRequest.stateChanges) {
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
     const { rawEntryInfos, deleteEntryIDs } = checkStateRequest.stateChanges;
     if (!rawEntryInfos && !deleteEntryIDs) {
-      return [entryStore, []];
+      return {
+        entryStore,
+        entryStoreOperations: [],
+        reportCreationRequests: [],
+      };
     }
 
     const updatedEntryInfos: { [string]: RawEntryInfo } = { ...entryInfos };
@@ -622,16 +674,21 @@
       mergedEntryInfos,
     );
 
-    return [
-      {
+    return {
+      entryStore: {
         entryInfos: mergedEntryInfos,
         daysToEntries: mergedDaysToEntries,
         lastUserInteractionCalendar,
       },
-      newInconsistencies,
-    ];
+      entryStoreOperations: [],
+      reportCreationRequests: newInconsistencies,
+    };
   }
-  return [entryStore, []];
+  return {
+    entryStore,
+    entryStoreOperations: [],
+    reportCreationRequests: [],
+  };
 }
 
 function mergeUpdateEntryInfos(
diff --git a/lib/reducers/master-reducer.js b/lib/reducers/master-reducer.js
--- a/lib/reducers/master-reducer.js
+++ b/lib/reducers/master-reducer.js
@@ -54,11 +54,8 @@
     reduceThreadInfos(state.threadStore, action);
   const { threadInfos } = threadStore;
 
-  const [entryStore, newEntryInconsistencies] = reduceEntryInfos(
-    state.entryStore,
-    action,
-    threadInfos,
-  );
+  const { entryStore, reportCreationRequests: newEntryInconsistencies } =
+    reduceEntryInfos(state.entryStore, action, threadInfos);
 
   const onStateDifferenceForStaff = (message: string) => {
     const isCurrentUserStaff = state.currentUserInfo?.id