Skip to content

fix(shared): keep native stack order when some saved layer lists are stale - #20388

Merged
juliusmarminge merged 4 commits into
pingdotgg:mainfrom
ScottN-PV:fix/20370-native-stack-order
Oct 20, 2026
Merged

juliusmarminge merged 4 commits into
pingdotgg:mainfrom
ScottN-PV:fix/20370-native-stack-order

Conversation

@ScottN-PV

@ScottN-PV ScottN-PV commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Native stacks can save different layer lists on different linked pull requests. Reading only the first saved list puts newly added layers before older layers and can select the wrong current PR.

Use the snapshot that covers the most linked stack members, then the longest list; ties retain the earliest stored snapshot. Listed members follow that order, and missing members follow in stable stored order. The reported example now orders 18, 20, 83, 84 and selects PR 84, instead of 83, 84, 18, 20 and PR 20.

Refs #20370. This is a focused selection fix: it does not refresh sibling snapshots or infer an unavailable host reorder. When every snapshot is stale, the best available snapshot can still be stale.

Verification on 4eaabc4f3e:

  • Reduced 6 added cases to 2 in the existing resolver suite: reported ordering/current-PR regression and stable partial-snapshot fallback. Resolver file: 47 → 43 tests; plus 2 existing list-line tests, 45 pass. Both regressions fail against main.
  • One independent full-diff review round with Claude Opus 5.5 and Codex GPT-6 Sol: no defects; reviewers independently passed the resolver and focused suites.
  • Shared typecheck, targeted lint/format, and diff checks pass. Existing coverage retains derived-chain, host/repository scoping, input immutability, and compatibility without ES2023 array methods.
  • Drove the isolated web app with the same synthetic saved snapshots on actual main and head. Current row changes from PR 20 to PR 84; expanded remaining rows change from 83, 84, 18 to 18, 20, 83 (the app displays current first). No backend sync was inferred from the direct visual fixture.
  • Shared callers include web, desktop, mobile, and MCP. Native macOS, Windows, iOS, Android, Electron desktop, and live GitHub stack sync were not verified.
Before: main selects PR 20 After: this head selects PR 84
Before: current PR 20 precedes misplaced new native layers After: current PR 84 with remaining layers in native order

Credit to @ScottN-PV for the original fix in #20388. The takeover preserves the contributor commits and production implementation after independent reassessment, merges current main, and removes redundant test cases.

Implementation: Codex GPT-6.1 Sol; tests: Codex GPT-6 Astra; independent reviews: Claude Opus 5.5 and Codex GPT-6 Sol, through T3 Code.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 16, 2026
@coderabbitai

coderabbitai Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Warning

Review limit reached

Only developers with an assigned seat can use this organization's usage-based review budget, and seats here are assigned manually. Ask an admin to assign a seat, or change the review continuation mode in Billing.

Next included review available in 12 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2f9cc136-d732-4ba1-8233-a99baad142f4
📥 Commits

Reviewing files that changed from the base of the PR and between dcf8bf4 and e6b85fc.

📒 Files selected for processing: 2
  • packages/shared/src/threadPullRequests.test.ts
  • packages/shared/src/threadPullRequests.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2e28823a-602b-4364-a4d8-59903892efaf
📥 Commits

Reviewing files that changed from the base of the PR and between 3b99fb2 and dcf8bf4.

📒 Files selected for processing: 2
  • packages/shared/src/threadPullRequests.test.ts
  • packages/shared/src/threadPullRequests.ts

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

📝 Walkthrough

Native pull-request stack reconstruction now selects the saved layer snapshot that covers the most observed members, using the longer snapshot to break coverage ties. Members absent from that snapshot sort after listed members. Tests cover overlapping and partial snapshots, chain and depth order, current top, and input link order.

Changes: Native stack ordering

Layer / File(s) Summary
Select and apply saved layer order
packages/shared/src/threadPullRequests.ts, packages/shared/src/threadPullRequests.test.ts
Ordering selects the candidate saved layer list with the greatest member coverage, preferring the longer list on ties. Members absent from the selected list sort after listed members. Tests check resolved ordering, chain and depth, current top, and preservation of input link order.

Priority: ⬇️ Low

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

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to dcf8b

No merge-blocking issue is identified; the change is ready for normal merge checks.

### Architecture Summary

Architecture risk: 🔵 Low · up to dcf8b

The change affects 1 system.

Changed systems: packages/shared

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/shared (library) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in packages/shared/src/threadPullRequests.test.ts: Adds cases with two stored-link orders and overlapping native snapshots. The tests expect the chain to include only linked layers [18, 20, 83, 84] in that order, with depths [0, 1, 2, 3]; the current stack’s top is 84, its open links are ordered [84, 83, 20, 18], and the input link order remains unchanged.
  • observed — Modified behavior in packages/shared/src/threadPullRequests.test.ts: Adds cases for partial native snapshots with conflicting or incomplete layer orders. The tests specify the expected resolved layer order for each snapshot set.
  • observed — Modified behavior in packages/shared/src/threadPullRequests.ts: Native stack ordering now chooses the candidate saved layers that covers the most observed member numbers, preferring the longer candidate when coverage ties. Members are then sorted by that list’s order, with unlisted members assigned an order after its listed layers. Previously, only the first member’s saved layers determined ordering, and unlisted members sorted at the beginning.
Pre-merge checks: Passed 4
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title is concise, specific, and accurately describes the native stack ordering fix for stale saved layer lists.
Description check Passed The description provides the problem, implementation details, linked issue, scope limits, focused verification results, screenshots, unverified environments, and agent attribution. It does not use the…
Full details: Description check

Explanation

The description provides the problem, implementation details, linked issue, scope limits, focused verification results, screenshots, unverified environments, and agent attribution. It does not use the template section headings and does not include an explicit maintainer approval comment or explain why approval was unnecessary, but the required information is otherwise substantially complete.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • 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.

@juliusmarminge

Copy link
Copy Markdown
Member

Taking over this one as maintainer for batch pull-request-06. I will keep the focused native-stack snapshot fix, reduce the tests to the needed regressions, and verify the ordering and current-PR behavior against main.

@juliusmarminge
juliusmarminge merged commit def1c3b into pingdotgg:main Oct 20, 2026
26 checks passed
Pipyakas pushed a commit to Pipyakas/t3code that referenced this pull request Oct 21, 2026
…stale (pingdotgg#20388)

Co-authored-by: Julius Marminge <julius0216@outlook.com>
(cherry picked from commit def1c3b)
aorwall added a commit to aorwall/t3code that referenced this pull request Oct 21, 2026
Merges `pingdotgg/t3code` `main` at `e64766c56a` (367 commits from
`143ab1606d`) into the fork. It branches from `main`; no other merge PR
is open.

## Numbers

- Landed: 2630 files from `git diff --stat HEAD^1 HEAD`, against 2629 in
the upstream range. The gap:
- Kept deleted: `pair.ts`, `pair.test.ts` and
`useDiscoveredLocalServers.test.ts`.
- Kept as fork files: `branding.test.ts` and
`addBrowserSurface.test.ts`.
- Extra on the merge side: four ported fork browser tests,
`fork/ThreadParentLine.tsx` and `inventory.json`.
- Fork delta: 812 files, down from 817.

## Conflicts (40, each by its preflight verdict)

- **Upstream's test prune (pingdotgg#22557):** upstream's deletions win,
fork-only tests stay, and fork adaptations of deleted upstream tests are
dropped.
- Upstream's deletion accepted for the `ThreadDetailsPrRows`,
`PreviewEmptyState`, `previewEmptyStateLogic`,
`projectScriptEditor.permissions` and `terminalSessionAvailability`
tests.
- Four fork browser tests are ported to the new
`require-disposable-render` pattern: ThreadForkDialog,
MoatlessArtifactChip, PreviewView.frame and MobileSidebarDrawer.
- **`threadRoutes.ts`, `ThreadRouteView.tsx`, `ChatView.tsx`:** take
upstream's `unlistedThreadDetail` (pingdotgg#19724), plus three fork changes:
  - An unlisted thread is "missing" once its subscription has failed.
- A closed thread is not redirected by `archivedAt`, because it is
absent from a Moatless listing and still opens by URL.
  - `onOpenRelatedThread` shows its toast only for a deleted shell.

The `unlisted-thread-adoption` inventory entry now owns
`threadRoutes.test.ts` and `ChatView.tsx`.
- **`AGENTS.md` (`decide`):** kept the fork bullet and appended
upstream's test rules and browser-test section.
- **Upstream's change with the fork delta re-stated:** `BranchToolbar`
(`showWorkspaceControls`), `GitActionsControl`, `ChatOverlayHosts`,
`FilePreviewPanel`, `projectFilesQueryState`, `usePreviewSession` (on
upstream's `inactiveAtom`) and `useThreadActions`.
- **`getSidebarForkParentThreadId`:** upstream removed it, so it moves
into `fork/ThreadParentLine.tsx`.
- **New inventory entries:** the `branding-test` path policy and the
`preview-session-use-atom-value` duplicate-add exception.
- **Sweep:** 19 owned-concern hits, all upstream-owned and taken as
upstream's. No new workflow.

## Feature classification

### Usable as-is
- Mermaid rendering through pele (pingdotgg#21472) and project icon previews
(pingdotgg#20372).
- Dialog and composer polish, PR panel fixes and centred tables.
- The Waiting thread state (pingdotgg#21500), which shows once the backend sends
`blockedOnThreadWait`.
- The even-pace tick on Limits (pingdotgg#22408).

### Unsupported in Moatless / needs implementation
- `device.easAccount` and EAS Simulator device hosts (pingdotgg#21841–pingdotgg#21846).
Added to the `UnsupportedMethodError` union, and the Integrations page
that holds them is already flag-gated.
- `projects.listIgnoredFiles` and the `ignoredFileListing` capability,
which "Add project to another machine" uses (pingdotgg#22180). Added to the
union. The dialog falls back to tracked files only while the capability
is absent.
- `pullRequests.changeBreakdown` (pingdotgg#22189, pingdotgg#22255). Its union already
carries `UnsupportedMethodError`, and the tooltip drops the split when
the call fails.
- T3 Connect reachability (pingdotgg#22172).
- Scheduled-task webhook filters and dedupe (pingdotgg#22194, pingdotgg#22234).
- `lastEventLoopStall` (pingdotgg#22213) and the `previewClose` scope (pingdotgg#22156).
- `compactIdleThreads` and `autoCompactThreshold` (pingdotgg#21682).
- MCP diff tools (pingdotgg#15464), the install id (pingdotgg#21506) and the writing-style
setting (pingdotgg#22203).

### Backend behavior to consider reproducing in Moatless
- **Settlement and waits:** `blockedOnThreadWait`, orphaned follow-ups
and delegated waits (pingdotgg#21499, pingdotgg#22581, pingdotgg#20037, pingdotgg#20025).
- **Stop and wake:** `latestRunStopRequested` stops a stopped
usage-limit thread from auto-resuming (pingdotgg#21114). A wake run settles when
the provider never opens the wake turn (pingdotgg#19196). Snooze survives a run's
completion (pingdotgg#22202, pingdotgg#17118).
- **Runs and shells:** run failures are persisted (pingdotgg#19646), and shell
updates coalesce for a slow client (pingdotgg#14859).
- **VCS:** bare repositories (pingdotgg#17340, pingdotgg#16688, pingdotgg#18152, pingdotgg#20368), stack
layers (pingdotgg#20415, pingdotgg#20388), VCS safety fixes (pingdotgg#15036, pingdotgg#19802) and PR
provider robustness (pingdotgg#18780).
- **Other:** update and restart safety (pingdotgg#22253), terminal and checkpoint
performance (pingdotgg#21242, pingdotgg#21291), resource metrics (pingdotgg#22122), provider
polling (pingdotgg#18851) and tool-token expiry (pingdotgg#18552, pingdotgg#19491).

`docs/fork/gaps.md` is updated under *Methods the backend does not
dispatch* and *Runtime fixes upstream made to its own server*.

## Verification

Full `verify.mjs` run: every check except `test` passes (duplicate-adds,
tripwires, resolution-check, unsupported-methods with ADD 2 / DROP 0 /
KEEP 2, lockfile, fmt, lint, typecheck and build).

Test failures and what was done about each:
- **Machine failures seen in earlier merges:** `shared` `AgentScope`,
`t3` `OrchestratorReplayFixtures` and `provider-opencode`
`OpenCodeServerLedger`. The `GitVcsDriver` and
`RepositoryIdentityResolver` partial-clone tests fail because of the
sandbox's `insteadOf` rewrite.
- **New and environmental:** `t3` `ProviderInstanceRegistry` reads the
sandbox's own `ANTHROPIC_*` and `CLAUDE_CONFIG_DIR`. With those unset,
all 9 of its tests pass.
- **`web`:**
- The fork's `AppRoot.test.tsx` broke on upstream's new `useEffect`
(pingdotgg#20886). It now stubs `useEffect` and passes.
- Four browser files failed to import in the parallel run and pass
alone.
- **Playwright:** 1.60 wants chromium build 1223, which this sandbox
lacks. Browser tests ran against 1243 through a symlinked
`PLAYWRIGHT_BROWSERS_PATH`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---
Moatless task:
https://moatless.soaplabstest.com/tasks/c3df6407-7ad0-483c-a46c-e8b603326150
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants