# fix\(server\): a fork's first /compact compacts its inherited history · PR \#24172 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/24172)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: merged

Source repository: pingdotgg/t3code

Source branch: fix/issue-24160

Target branch: main

Head commit: 2615e21decad822bf4dd520cf103f9a8e33d49df

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/24172)

[Commits](https://git.cafe/pingdotgg/t3code/pull/24172/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/24172/diffs?format=markdown)

## Description

---

## Problem

Fork a Claude conversation from a completed response and send `/compact` as the fork's first message. The server rejects it with “Cannot compact an empty thread” even though the fork inherits the source conversation.

## Change

Both SQLite and in-memory projections recognize inherited conversation in run forks. Native forks qualify through their provider history; portable forks qualify when their resolved handoff contains historical messages. Empty portable handoffs and ordinary empty threads retain the existing rejection.

## Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/24160

Triaged bug via the automated issue flow: [#24160](https://git.cafe/pingdotgg/t3code/issues/24160).

## Verification

- From `apps/server`: `vp test run src/orchestration-v2/TurnStartReads.test.ts src/orchestration-v2/ProviderTurnStartService.test.ts src/orchestration-v2/ThreadFork.execution.test.ts` — **41 passed across 3 files**. [Raw green output](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/67921fafb9249f85/green-final.txt).
- Native-fork regression fails against the original implementation; empty-portable regression fails against the initial blanket-fork fix. Each execution run reports one failed and four passed tests. [Native red](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/93091eb71f5f7990/prefix-run.txt), [portable-empty red](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/8800a39b17163405/red-final.txt), [original SQLite/memory red](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/bd0acb09852cbdd6/red-evidence.log).
- The portable fixture forks across providers with two 17,000-byte messages omitted whole by the handoff budget. First-message `/compact` rejects before a provider session opens; the same-provider native case opens its session.
- Changed-file [lint](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/aa769866c3c61c33/lint.txt) and server [typecheck](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/1e3cf212cb116da2/typecheck.txt) passed; typecheck emits existing Effect suggestions. Both independent reviewers returned MERGE on the final revision.
- Real web client, Linux fs-35, Chromium at 1280×800, isolated dev server, Claude Opus 5.5. [Final runtime transcript](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/eb7a4cd8ad2dafc4/runtime-head-2615.md), [exact persisted rows](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/298c32e4114318eb/runtime-head-2615.json), [evidence provenance](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/7244ed31cb6e4886/evidence-provenance.md).

| Scenario | Before: [66ee628e08](https://git.cafe/pingdotgg/t3code/commit/66ee628e0875b2b735b199f42e6151e347833637) | After: [2615e21](https://git.cafe/pingdotgg/t3code/commit/2615e21decad822bf4dd520cf103f9a8e33d49df) |
| --- | --- | --- |
| Three completed parent turns → native fork third response → first own message `/compact` | Fails with empty-thread error | First run completes; 84,252 → 1,586 tokens |
| Empty nonfork → first message `/compact` | Rejects as empty | Rejects as empty; zero provider turns |
| Existing fork → normal message → `/compact` | Compacts successfully | Normal-conversation path remains covered |

[Before runtime transcript](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/96597bdd01f47b24/runtime-transcript.txt). No client rendering changes: the server-only proof exception applies, with an [empty capture matrix](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/b0ac4d25b7841fc3/proof-matrix-updated.md), red tests and runtime transcript. Shared server behavior applies to web, desktop, mobile and remote connections; runtime integration was exercised with Claude through the web client. No platform-specific code changed.

Models: GPT-6.1-Sol and Claude Opus 5.5. Harnesses: Codex and Claude Agent through T3 Code.

