Skip to content

fix(server): retained forks keep inherited counts after source deletion - #36640

Closed
StiensWout wants to merge 1 commit into
pingdotgg:mainfrom
StiensWout:t3/fix-fork-visible-count
Closed

StiensWout wants to merge 1 commit into
pingdotgg:mainfrom
StiensWout:t3/fix-fork-visible-count

Conversation

@StiensWout

Copy link
Copy Markdown
Contributor

Deleting a fork's source makes its shell count forget inherited items, so MCP thread listings report too few items even though the full projection retains them.

Both shell readers now share an ancestor walk that includes deleted sources. Target reads still exclude deleted threads; fork cutoffs, rollback handling and ancestor query bounds remain intact.

Found by the GPT 6.1 Sol bughunt and independently confirmed by Claude Opus 5.5 on main. The recorded-provider replay fails before the fix and passes after it. The permanent regression extends the existing projection-store rollback case, covering direct and nested forks through snapshot and single-thread reads, plus deleted-root exclusion. Reverting the fix makes that test fail; restoring it passes.

Validation: pnpm exec vp run check:changed and the ProjectionStore, ThreadFork.integration, ThreadFork.execution and OrchestratorMcpService test files pass on the pinned Node version in boat.dev. No client-visible defect is claimed, so no browser scenario applies.

Size: medium, confined to the projection store and its existing tests, with no schema or storage change. Fast lane. Local cubic found no issues; repository context was unavailable for the fork.

Council review

Reviewer Round 1
Claude Opus 5.5 9/10
GPT 6.1 Sol 9/10

No blocking findings. Retained nits: deleting a middle ancestor is not separately exercised, and the regression extends a complex existing rollback case. The shared traversal covers deleted ancestors at every depth; the supplied integration replay also proves the original idle-fork failure. Existing duplicated shell assembly and heavy ancestor queries are follow-ups outside this fix.

Created with GPT 6.1 Sol (lead and review) and Claude Opus 5.5 (build, trim and review) in T3 Code through the Codex and Claude harnesses.

Closes #36639

…urce is deleted

Shell reads walked fork ancestors through the same selector as their
targets, which skips deleted threads. Once a fork's source was deleted,
readShellSnapshot and getThreadShell fell back to the fork's own items,
so visibleItemCount (and the MCP thread list's itemCount) dropped to the
fork's local count while its full projection still held the inherited
history. Both readers now share one ancestor walk that includes deleted
ancestors; target rows still exclude deleted threads.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: GPT 6.1 Sol <codex@openai.com>
@github-actions github-actions Bot added vouch:trusted Author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Nov 14, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at e994602

Macroscope's review found this PR approvable — Retained forks now include deleted ancestors when calculating inherited item counts. Deleted threads remain excluded from returned shell listings, and the change does not modify stored data.

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

@coderabbitai

coderabbitai Bot commented Nov 14, 2026

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Shell reads now load deleted fork ancestors when calculating inherited visible-item counts. Deleted threads remain excluded as shell targets. Regression assertions cover source visibility and retained fork counts.

Changes: Retained fork shell counts

Layer / File(s) Summary
Deleted ancestor selection
apps/server/src/orchestration-v2/ProjectionStore.ts
selectShellThreadRows can include deleted threads. A shared traversal loads fork ancestors, including deleted ancestors, while avoiding duplicate rows.
Shell reads and regression coverage
apps/server/src/orchestration-v2/ProjectionStore.ts, apps/server/src/orchestration-v2/ProjectionStore.test.ts
Shell snapshot and single-thread reads use the shared traversal. The regression test checks that deleted sources remain hidden and target and nested-fork counts match their projections.

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

Change: Bug fix · Severity of issue fixed: Low

Suggested reviewers: juliusmarminge, yash-singh1

Merge Risk: Minimal · up to e9946

This change restores inherited item counts for forks whose source thread has been deleted. Deleted threads stay hidden as shell targets. No merge-blocking risk was found, and the regression test covers the main scenarios.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title names the main change: fork shell reads keep inherited item counts after the source thread is deleted. It follows the conventional commit format and matches the PR objectives and linked issu…
Description check Passed The description covers the problem, the change, scope with a linked issue (#36639), and verification with specific tests and results. It also includes the council review table and the model attributio…
Linked Issues check Passed Issue #36639 requires that a retained fork's shell visibleItemCount include inherited visible history after its source is deleted, matching the full projection, while the deleted source stays hidden. …
Out of Scope Changes check Passed The changes are confined to apps/server/src/orchestration-v2/ProjectionStore.ts and ProjectionStore.test.ts, per the supplied summary. The ProjectionStore.ts change adds an includeDeleted option and a…
Full details: Title check

Explanation

The title names the main change: fork shell reads keep inherited item counts after the source thread is deleted. It follows the conventional commit format and matches the PR objectives and linked issue #36639.

Full details: Description check

Explanation

The description covers the problem, the change, scope with a linked issue (#36639), and verification with specific tests and results. It also includes the council review table and the model attribution line that the template requests. It does not describe screenshots, which do not apply because the change has no UI impact. Its problem statement is stated briefly, and the Scope section links an issue but does not explain why the fix needs no feature work. The description is mostly complete.

Full details: Linked Issues check

Explanation

Issue #36639 requires that a retained fork's shell visibleItemCount include inherited visible history after its source is deleted, matching the full projection, while the deleted source stays hidden. The PR summary states that selectShellThreadRows gains an includeDeleted option (default false). Shell snapshot and single-thread shell reads use a shared ancestor traversal that enables it for fork sources, so deleted ancestors contribute inherited counts. Target threads keep the deletion filter, so the deleted source stays hidden. The regression test extends the existing ProjectionStore rollback case. It covers direct and nested forks through snapshot and single-thread reads, plus deleted-root exclusion. The author reports that the recorded-provider replay fails before the fix and passes after it. The MCP itemCount path in the issue is not covered by a new test. It is inferred to derive from the same shell snapshot, and the reported OrchestratorMcpService test run passes. Evidence basis: the supplied PR summary and test description. The source diff could not be read because changed blobs were missing from the checkout, so the code-level behavior is established from the summary only.

Full details: Out of Scope Changes check

Explanation

The changes are confined to apps/server/src/orchestration-v2/ProjectionStore.ts and ProjectionStore.test.ts, per the supplied summary. The ProjectionStore.ts change adds an includeDeleted option and a shared ancestor traversal used by the two shell readers. The test change extends the existing fork-history regression. Both connect directly to the reported defect. The summary reports no schema, storage, or exported-declaration change. Limit: the source diff could not be read, so this verdict relies on the supplied summary.

Finishing Touches

Generate unit tests (beta)

  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between 13f89ae and e994602.

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; 2 remain after this review.

@juliusmarminge

Copy link
Copy Markdown
Member

Thanks for this. #32760 makes the same change and is the one being kept.

#32760 already fixes the same deleted-source count mismatch in both shell readers. It makes the smaller production change by enabling deleted-ancestor reads in the existing walks, without extracting a shared traversal.

Your regression adds useful coverage for nested forks after source rollback. That coverage could strengthen the existing fix without carrying a second implementation of the same behavior.

Closing as a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:trusted Author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Retained forks lose inherited shell item counts after source deletion

2 participants