MacroscopeApp / Macroscope - Correctness Check
succeeded
Sep 1, 2026 in 3m 24s
No issues identified (59 code objects reviewed).
• Merge Base:
0bfb6df
• Head:c55dd68
Details
| ✅ | File Path | U3 Bytes | Comments Posted | Reason |
|---|---|---|---|---|
| ✅ | apps/web/src/hooks/useThreadViewState.ts |
8989 | 0 | |
| ✅ | docs/user/thread-sidebar.md |
917 | 0 | |
| ➖ | apps/web/src/hooks/useThreadViewState.test.ts |
17307 | Excluded by default ignore patterns | |
| ✅ | apps/mobile/src/features/threads/threadViewState.ts |
3053 | 0 | |
| ✅ | apps/web/src/state/entities.ts |
644 | 0 | |
| ➖ | apps/server/src/orchestration/decider.viewState.test.ts |
14775 | Excluded by default ignore patterns | |
| ➖ | apps/mobile/src/features/threads/threadViewState.test.ts |
5124 | Excluded by default ignore patterns | |
| ✅ | packages/contracts/src/environment.ts |
581 | 0 | |
| ✅ | apps/server/src/persistence/Migrations/044_ProjectionThreadsViewedAt.ts |
1023 | 0 | |
| ✅ | apps/web/src/components/ChatView.logic.ts |
1753 | 0 | |
| ➖ | packages/contracts/src/environment.test.ts |
560 | Excluded by default ignore patterns | |
| ➖ | apps/server/src/persistence/Migrations/044_ProjectionThreadsViewedAt.test.ts |
4073 | Excluded by default ignore patterns | |
| ✅ | apps/server/src/relay/AgentAwarenessRelay.ts |
464 | 0 | |
| ✅ | apps/mobile/src/state/use-thread-selection.ts |
268 | 0 | |
| ✅ | apps/server/src/orchestration/decider.ts |
5151 | 0 | |
| ✅ | apps/server/src/persistence/Migrations.ts |
714 | 0 | |
| ➖ | apps/server/src/orchestration/projector.test.ts |
191 | Excluded by default ignore patterns | |
| ✅ | apps/server/src/environment/ServerEnvironment.ts |
265 | 0 | |
| ✅ | apps/server/src/orchestration/projector.ts |
538 | 0 | |
| ✅ | packages/client-runtime/src/state/threadDetail.ts |
247 | 0 | |
| ➖ | apps/server/src/relay/AgentAwarenessRelay.test.ts |
867 | Excluded by default ignore patterns | |
| ➖ | packages/client-runtime/src/state/runtime.test.ts |
1925 | Excluded by default ignore patterns | |
| ✅ | packages/client-runtime/src/state/threadReducer.ts |
318 | 0 | |
| ➖ | apps/server/src/environment/ServerEnvironment.test.ts |
501 | Excluded by default ignore patterns | |
| ➖ | apps/server/src/orchestration/projector.settled.test.ts |
979 | Excluded by default ignore patterns | |
| ✅ | packages/client-runtime/src/operations/commands.ts |
1241 | 0 | |
| ➖ | packages/client-runtime/src/state/threadReducer.test.ts |
909 | Excluded by default ignore patterns | |
| ➖ | apps/web/src/components/ChatView.logic.test.ts |
3969 | Excluded by default ignore patterns | |
| ✅ | apps/server/src/persistence/Services/ProjectionThreads.ts |
347 | 0 | |
| ➖ | apps/web/src/uiStateStore.test.ts |
5183 | Excluded by default ignore patterns | |
| ➖ | packages/client-runtime/src/operations/commands.test.ts |
1741 | Excluded by default ignore patterns | |
| ➖ | packages/client-runtime/src/state/entities.test.ts |
664 | Excluded by default ignore patterns | |
| ➖ | apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts |
2171 | Excluded by default ignore patterns | |
| ➖ | apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts |
2467 | Excluded by default ignore patterns | |
| ✅ | apps/server/src/orchestration/Layers/ProjectionPipeline.ts |
578 | 0 | |
| ➖ | packages/contracts/src/orchestration.test.ts |
3953 | Excluded by default ignore patterns | |
| ✅ | packages/contracts/src/orchestration.ts |
2340 | 0 | |
| ✅ | packages/client-runtime/src/state/threadCommands.ts |
1652 | 0 | |
| ✅ | apps/web/src/components/ThreadStatusIndicators.tsx |
1288 | 0 | |
| ➖ | apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts |
498 | Excluded by default ignore patterns | |
| ✅ | apps/server/src/persistence/Layers/ProjectionThreads.ts |
1300 | 0 | |
| ✅ | apps/mobile/src/features/threads/ThreadRouteScreen.tsx |
4358 | 0 | |
| ✅ | apps/web/src/uiStateStore.ts |
6254 | 0 | |
| ✅ | apps/web/src/hooks/useThreadActionMenu.ts |
1724 | 0 | |
| ✅ | apps/web/src/hooks/useThreadActions.ts |
2545 | 0 | |
| ✅ | apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts |
3302 | 0 | |
| ✅ | apps/web/src/components/LegacySidebar.tsx |
3599 | 0 | |
| ✅ | apps/web/src/components/Sidebar.tsx |
3484 | 0 | |
| ✅ | apps/web/src/components/ChatView.tsx |
6040 | 0 |
Billed Total: 52.23KB of diff | $2.61
Saved $0.64 vs. the upper-bound estimate of $3.25 — cached code objects from prior reviews on this PR were not re-billed.
Filtered Issues Details
apps/mobile/src/features/threads/ThreadRouteScreen.tsx
- line 301: The tracking effect cannot schedule a retry after
thread.viewis capped by the server clock.resolveThreadViewTrackingStateonly producesretryBoundarywhen the returnedviewedAtexactly matches a requested boundary, but the server explicitly caps a futureviewedThroughto its current time. When a mobile client has received acompletedAtlater than that server clock, the resulting marker remains below completion and matches no requested boundary, leavingthreadViewRetryBoundaryunchanged; the focused callback is not recreated, so the thread stays unread until some unrelated focus/dependency change. [ Already posted ]
apps/mobile/src/features/threads/threadViewState.ts
- line 46: The timestamp-only match at
Date.parse(requestedBoundary) === viewedAtMscannot distinguish this device's view response from a remotethread.mark-unread. If this device previously requested a view at completionT, and another client marks a subsequent completion atT + 1msunread, the server storesT(completedAt - 1ms). This function treats that remote unread marker as its own applied request, changesretryBoundary, and the focus callback immediately sends a guarded view that matches and overwrites the other client's explicit unread action. [ Already posted ] - line 46:
resolveAppliedThreadViewBoundaryonly recognizes a server-applied view when its timestamp exactly equals a requested boundary. The server can cap a futureviewedThroughboundary to its current time, leavingviewedAt < completedAtbut unequal to every requested boundary. In that case this returnsundefined, soretryBoundarydoes not change and the focused screen does not issue the needed retry when that completion boundary becomes reachable; the completed thread remains unread until another dependency/focus transition happens. [ Already posted ]
apps/web/src/components/ChatView.logic.ts
- line 102:
shouldAcknowledgeVisibleThreadCompletioncompares unvalidated strings withDate.parse.IsoDateTimeis currentlySchema.String, so a malformedcompletedAt(or persisted local view timestamp) is accepted;Date.parseyieldsNaNand the comparison is false. After the initial local-only acknowledgement, capability discovery therefore never synchronizes the view state to the server, leaving the thread unread on other clients. [ Already posted ]
apps/web/src/components/ChatView.tsx
- line 1875: The completion acknowledgement at
markViewed(threadRef, completedAt, supportsThreadViewState)treats its RPC as complete once its event sequence arrives, even if the server capped a futurecompletedAtto its current time. The server explicitly performs that cap, leavingviewedAt < completedAt; however this effect does not depend onviewedAtor pending-state changes, so it will not retry while the tab remains focused. A server clock rollback or a future completion boundary therefore leaves other clients showing the thread unread until the user changes focus or reopens it. [ Already posted ]
apps/web/src/hooks/useThreadActionMenu.ts
- line 235:
markUnreadfalls back tomarkLocalUnreadwhen the environment capability has not loaded and the shell lacksviewedAt, without recording pending state or retrying. Thus, selecting Mark unread from this header menu during startup creates only a local marker; when configuration later confirms view-state support, the action is never sent to the server and other clients remain read. [ Already posted ]
apps/web/src/hooks/useThreadViewState.ts
- line 136:
markViewedtreats an unavailable server configuration and a shell withoutviewedAtas an unsupported server at lines 132-138, then only writes the local marker. That path creates no pending entry or retry, so a user action made before the configuration/shell finishes loading is never sent whenthreadViewStatelater proves supported; other clients continue to show the thread unread. [ Already posted ] - line 190:
markUnreadfalls back tomarkLocalUnreadwhen the environment config has not loaded and the shell does not yet exposeviewedAt(lines 190-198). Unlike a rejected server operation, this fallback records no pending intent to resume, so marking a thread unread during startup remains local after the server capability arrives and does not synchronize to other clients. [ Already posted ]
Loading