Skip to content

Standardized messages - #11

Closed
t3dotgg wants to merge 2 commits into
mainfrom
theo/standardize-messages
Closed

t3dotgg wants to merge 2 commits into
mainfrom
theo/standardize-messages

progress but not really

58c10bb
Select commit
Loading
Failed to load commit list.
MacroscopeApp / Macroscope - Correctness Check completed Feb 12, 2026 in 23m 54s

5 issues identified (178 code objects reviewed).

• Merge Base: 5120f7f
• Head: 58c10bb

Details

✅ File Path Comments Posted
✅ AGENTS.md 0
✅ README.md 0
✅ apps/server/src/codexAppServerManager.ts 0
✅ apps/server/src/providerEventNormalizer.ts 0
✅ apps/server/src/providerManager.ts 0
❌ apps/server/src/providerStreamStore.ts 2
❌ apps/server/src/providerStreamSubscriptionManager.ts 1
✅ apps/server/src/wsServer.ts 0
✅ apps/web/src/App.tsx 0
✅ apps/web/src/components/ChatView.tsx 0
✅ apps/web/src/session-logic.ts 0
✅ apps/web/src/store.ts 0
✅ apps/web/src/types.ts 0
❌ apps/web/src/wsNativeApi.ts 1
❌ apps/web/src/wsTransport.ts 1
✅ docs/provider-ws-api.md 0
✅ packages/contracts/src/ipc.ts 0
✅ packages/contracts/src/provider.ts 0
✅ packages/contracts/src/providerStream.ts 0

Filtered Issues Details

apps/server/src/providerEventNormalizer.ts
  • line 445: In ProviderEventNormalizer.normalize, the handler for turn/plan/updated (lines 437-462) assigns raw.id directly to activityId (line 445) without validation. If the raw event object lacks an id property, activityId becomes undefined. This creates an activity event with a missing identifier, which violates the implied contract that activities must be trackable entities. Downstream lookup or rendering logic relying on activityId as a key or identifier may fail or behave unpredictably. [ Already posted ]
apps/server/src/providerStreamStore.ts
  • line 323: The pruneReplayLog method contains an infinite loop hazard. The while loop checks this.replayLog.length > 0, but the termination condition inside relies on three boolean flags (overCount, overBytes, tooOld). If the loop enters (because the log is non-empty) but none of those conditions are met (e.g., log is under limits), it returns. However, if any condition is met (e.g., overCount is true), it shifts one element and continues. The critical flaw is that this.replayBytes is decremented by first.encodedSize. If first.encodedSize is 0 or negative (unlikely but possible if eventSizeBytes returns 0 for empty JSON), replayBytes might not decrease effectively. More importantly, if overCount is true, it shifts an element. This seems safe. However, there is a subtle issue: the loop logic if (!overCount && !overBytes && !tooOld) { return; } correctly breaks when limits are satisfied. But if this.replayLog is somehow empty, first becomes undefined. The check if (!first) { return; } handles this. The logic seems mostly sound for standard execution, but there is no safeguard against replayBytes becoming negative if accounting drifts or encodedSize is calculated differently on removal than insertion. While not a strict infinite loop in the local logic shown (since shift() reduces length), this.replayBytes management is fragile. Actually, looking closer at pruneReplayLog: if overCount is true, we shift. This reduces length. If overBytes is true, we shift. This reduces bytes. If tooOld is true, we shift. This reduces length. The loop is bounded by replayLog.length. So it terminates. [ Already posted ]