fix(server): avoid reparsing streamed replies for timestamps#25252

open4
main
fix/issue-25157
opened6d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 1d ago

Problem

Every streamed reply update encodes its projection payload and then parses the entire JSON again just to read timestamps. Asking an agent for a long reply makes this redundant work grow with the reply inside the write transaction.

Change

Encode timestamps directly from the typed payload with the same codec used by payload JSON. This removes the extra parse from message.updated and turn-item.updated, preserving stored timestamps and upsert behavior.

Scope and approval

Fixes pingdotgg/t3code#25157

Triaged bug via the automated issue flow. Focused server-only fix for #25157. The contributor's #25162 addresses the same issue; this PR adds a failing performance regression test and verified live-server proof on current main.

Verification

  • Red: the 128 KiB regression fails on main, identifying both message and turn-item payloads passed to JSON.parse.
  • Green: all 47 projection-store tests pass. The regression also verifies indexed timestamps including milliseconds.
  • vp run check:changed: format, lint, knip, GraphQL, affected typechecks and focused tests pass after merging current main.
  • Independent GPT-6.1-Sol and Claude Opus 5.5 reviews: MERGE. Server proof audit: SUFFICIENT.
  • Real isolated dev server with Codex: repeated streaming upserts grew from 607 to 9,756 bytes, completed through both affected event types, and survived browser reload. Zero matching redundant projection parses; zero indexed timestamp mismatches. The 128 KiB case is automated coverage; the live reply was 9,756 bytes. No end-to-end latency benchmark claim.
  • No rendering changes; visual fixture matrix is empty. Shared server path applies to web, desktop, mobile and remote connections; client-specific captures are unnecessary.

Evidence: runtime transcript, committed updates and timestamp checks, parse probe output. Reproduction tools: inspector probe, read-only SQL summary.

Written by GPT-6.1-Sol in T3 Code (Codex harness), with Claude Opus 5.5 test, implementation and review tasks.

Checks

20 successful · 20 skipped
All checks passed
464d77d

Added 3 commits

  • Merge remote-tracking branch 'origin/main' into fix/issue-25157b79914d
  • test(server): streamed projection payloads are not re-parsed for timestampse08df27
  • fix(server): index streamed projection timestamps without re-parsing payloadsfd5d545
Synced from GitHub

Approvability

Verdict: Approved at b79914d

Macroscope's review found this PR approvable — This is a narrow server-side fix that removes redundant parsing of large streamed payloads while preserving timestamp encoding and persistence behavior. The accompanying regression test verifies both affected event types and timestamp precision.

No code changes detected at 464d77d. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB−35 B (−0.7%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.3 KiB1.2 KiB−35 B (−2.7%)2.0 KiB✅
CodexLive turn WebSocket decoded21.6 KiB21.5 KiB−41 B (−0.2%)24.4 KiB✅
CodexLive turn messages21−1 (−50.0%)8✅
ClaudeTotal thread wire5.0 KiB5.0 KiB0 B (0.0%)6.8 KiB✅
ClaudeThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
ClaudeLive turn WebSocket wire1.3 KiB1.3 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.9 KiB21.9 KiB0 B (0.0%)24.4 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: 97e35bc · PR result: 464d77d · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between b79914d19940449f2c412cad8ba64f07330fc77a and 464d77df25806d9e37b7524ce3d59c51fc4d4d51.

External image Files selected for processing: 2
  • apps/server/src/orchestration-v2/ProjectionStore.test.ts
  • apps/server/src/orchestration-v2/ProjectionStore.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 4 remain after this review.

Walkthrough

ProjectionStore now encodes message and turn-item index timestamps directly from event payloads. A regression test checks the stored timestamps and verifies that large streamed payload text is not parsed to retrieve them.

Changes: Projection timestamp indexing

Layer / File(s)Summary
Direct timestamp encoding and regression test
apps/server/src/orchestration-v2/ProjectionStore.ts, apps/server/src/orchestration-v2/ProjectionStore.test.ts
A shared UTC timestamp encoder supplies message and turn-item index values. The regression test checks the stored timestamps and verifies that the large payload text is not parsed to retrieve them.

Priority: External image Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related PRs

  • pingdotgg/t3code#24145: This PR changes the same ProjectionStore handlers and compares indexed fields before writing.

Suggested reviewers: t3dotgg, maria-rcks

Merge Risk: External image Minimal · up to 464d7

The change indexes timestamps directly without changing payload storage. No merge-blocking risk is identified.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title is concise, conventional, and accurately identifies the server fix: avoiding repeated parsing of streamed replies to read timestamps.
Description checkPassedThe description includes Problem, Change, Scope and approval, and Verification sections. It explains the issue, implementation, linked issue, tests, live-server checks, limitations, and agent attribut…
Linked Issues checkPassedDirectly linked issue [#25157] requires message.updated and turn-item.updated to index timestamps without parsing the full streamed payload. ProjectionStore.ts now encodes timestamps from the ty…
Out of Scope Changes checkPassedThe changes are limited to the server projection store and its focused regression test. The implementation directly addresses [#25157]. The test validates the implementation and stored timestamp behav…
Full details: Description check

Explanation

The description includes Problem, Change, Scope and approval, and Verification sections. It explains the issue, implementation, linked issue, tests, live-server checks, limitations, and agent attribution. The scope section does not include an explicit maintainer approval comment, but the description is otherwise complete and focused.

Full details: Linked Issues check

Explanation

Directly linked issue [#25157] requires message.updated and turn-item.updated to index timestamps without parsing the full streamed payload. ProjectionStore.ts now encodes timestamps from the typed event payload with Schema.DateTimeUtcFromString. The existing payload encoding and upsert behavior remain unchanged. The regression test covers both event types, a 128 KiB streamed payload, no matching full-payload parse, and millisecond timestamp indexes. The separate ws.ts concern is explicitly optional and is not required by this PR.

Full details: Out of Scope Changes check

Explanation

The changes are limited to the server projection store and its focused regression test. The implementation directly addresses [#25157]. The test validates the implementation and stored timestamp behavior. No unrelated rendering, client, or ws.ts changes are included.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Added 1 commit

  • Merge branch 'main' into fix/issue-25157464d77d