fix(server): show Claude project skills before command discovery completes#23114

open3
main
fix/issue-22429
opened11d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 10d ago

Problem

After a Claude thread's workspace snapshot is evicted by scans of 16 other folders, its $ picker temporarily shows only personal skills. Project skills wait for a fresh Claude capability probe even though filesystem skill discovery has already finished.

Change

Publish discovered Claude workspace skills before the capability probe, with slash commands pending. Partial and final results use the same registry ownership and freshness guards. The final result replaces its own partial publication; the 16-workspace cap remains.

Other providers keep their existing one-result discovery path. No wire schema or client rendering changes.

Scope and approval

Fixes #22429 GitCafe: https://git.cafe/pingdotgg/t3code/issues/22429 Triaged bug via the automated issue flow. One reproduced cache-eviction timing defect; no authentication, permission, mode, sandbox, or MCP changes.

Verification

  • Main reproduction: 17 real worktrees of one repository, each with a project-only Claude skill. Returning to the first after scanning the other 16 temporarily showed personal skills only; repeated with a filtered skill query.
  • Red test committed before the fix: the registry had no project skills while a Deferred held command discovery after eviction. After the fix, the same test observes skills with commands pending, then final commands and cleared pending state.
  • Post-merge vp run check:changed: formatting, targeted lint, Knip, generated GraphQL verification, affected-package typechecks, and the full registry test file (38/38) passed.
  • Additional implementation checks: Codex/Antigravity discovery test files (29/29), Pi driver tests (5/5), server and provider-core typechecks passed.
  • Two isolated code reviews returned MERGE. The actual PR diff after merging current main is byte-identical to the reviewed diff.

Evidence matrix

Before: beec3c8b30ce. After: 26c41f4c7fa8.

Formal static render matrix: empty ([]). The changed paths are server/provider internals; the four rows below are supplemental interaction recordings. No still-image/pixel-diff claim is made. The pass-1 matrix and audit are in the linked support bundle; independent pass-2 proof audit passed all six required evidence rows.

Script and observed ordering

Same 17 stopped fixture threads and project skill on both isolated servers. A is folder 02. Prime A, type $triage, visit 03–17 then 01 sequentially and await each real settled snapshot, prove A absent with 16 cached folders, return A within 15–21 seconds, keep $triage visible through discovery, then show / and query /compact. No turns sent. The actual /compact query suggests /autocompact on both sides; the unchanged final provider snapshot contains 70 command names.

Before: the project row is missing while the personal skill remains, then appears only after final command publication. After: the project row becomes visible with slashCommandsPending:true, 448–744 ms before final publication in these runs. A brief filesystem-discovery gap remains; this eliminates the slow CLI interval, not every millisecond of absence. All recorded snapshot lists stay at or below 16.

Width / themeBefore: pending at project visibilityAfter: project visible before final publication
1440 / lightNo562 ms; pending=true
1440 / darkNo744 ms; pending=true
390 / lightNo448 ms; pending=true
390 / darkNo573 ms; pending=true

Rebuild, transcript and audit metadata

Rebuild guide · Support bundle: scripts, fixture creation data, pass-1 audit/matrix, provenance, probe spans, red/green logs · Ordered live runtime transcript · Capture audit metadata

The transcript subscribes to the real appAtomRegistry / serverEnvironment.providersValueAtom and observes actual DOM mutations. It records cwd, skill/pending/count milestones and the final real command names. Server workspace-probe spans are correlated by timestamp; they lack cwd attributes and an independent CLI subprocess span, so no exact CLI launch/completion claim is made. Parent-provided green log labels the final head and reports 38 focused tests passing. Historical red output lacks an in-band invocation/SHA; its provenance limit is retained in metadata.

What else changed and rendering

The intended visible difference is the transient project row during discovery. Final command names match across all eight runs. Live age badges differ with capture time, and caret/text selection plus recording frame sampling vary while typing; no pixel-identity claim is made. The same responsive route navigation, viewport, theme, fixture, provider and scroll position are used per pair. Sidebar filtering hides unrelated threads; update notifications were dismissed. A02 avoids a separate active A01 client refreshing its own evicted cwd.

Tool/browser: T3 collaborative Browser, Chrome 154 on Linux. No device emulation; freeform 1440×900 or 390×900 CSS viewport, DPR 2, visual viewport scale 1, root font 16px, text-size-adjust 100%. Complete native viewport footage is 2880×1800 or 780×1800. A 240-native-pixel caption band sits outside the app; the original recording is uncut and retains its speed, with a labelled four-second final-frame hold. Captions narrate script and browser-clock milestones; compositor/video frames are not perfectly synchronized to DOM subscription timestamps. No artificial provider delays, fake snapshots or synthetic component fixtures were used.

Served Vite source-map originals for five relevant runtime/client files per checkout match the exact git refs. Server cwd/start times and observed partial/final behavior support runtime provenance; no in-process build hash endpoint exists. The before server predates the merge-base checkout, but all four changed runtime files are byte-identical between its original base and the final base.

Limits and publication

Native iOS/Android, desktop shell, remote/relay and multi-device runtime timing remain unverified. Clean-room reseeding was not executed: rebuild scripts were syntax/source checked and captures reused the parent’s fixture. Personal skill source files and unrelated data are excluded. Independent pass-2 proof audit passed; this is evidence for review, not merge approval.

Before upload, both required cafe issue reads succeeded with zero comments and complete pagination; no recent MEMBER/OWNER comment existed. No repository edits, commits, pushes, issue/PR writes, new dev servers or agent turns were made by this capture task.

Unverified: Electron shell, native iOS/Android, remote/relay/tunnel, multi-device, cancellation and instance replacement at runtime. Their code paths are unchanged. Filesystem discovery still takes its normal time; this removes the wait on the slow command probe.

Implementation: Claude Opus 5.5 via Claude Agent SDK; triage, integration and evidence: GPT-6.1-Sol via Codex; independent code/proof reviews: GPT-6.1-Sol via Codex and Claude Opus 5.5 via Claude Agent SDK.

Checks

3 failing · 20 successful · 12 skipped
Some checks failed

Failing3

26c41f4

Added 3 commits

  • Merge main into fix/issue-2242926c41f4
  • fix(server): Claude skills show while its command probe runsce22309
  • test(server): reproduce evicted folder skills hidden during slow command probefcda42d
Synced from GitHub

Approvability

Verdict: Approved at 26c41f4

Macroscope's review found this PR approvable — This is a focused server bug fix that exposes already-discovered Claude project skills during the existing slow command probe, then preserves the established final snapshot behavior. The change is localized, backward-compatible for other providers, and covered by a regression test.

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

Synced from GitHub

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

ℹ️ The exact PR base did not have a successful artifact. Baseline uses the latest successful main measurement shown below.

ProviderMetricMain baselineThis PRImpactPR ceiling
CodexTotal thread wire5.0 KiB5.0 KiB−7 B (−0.1%)6.8 KiB✅
CodexThread snapshot wire3.8 KiB3.8 KiB0 B (0.0%)4.9 KiB✅
CodexLive turn WebSocket wire1.2 KiB1.2 KiB−7 B (−0.6%)2.0 KiB✅
CodexLive turn WebSocket decoded20.9 KiB20.9 KiB0 B (0.0%)29.3 KiB✅
CodexLive turn messages220 (0.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.2 KiB1.2 KiB0 B (0.0%)2.0 KiB✅
ClaudeLive turn WebSocket decoded21.2 KiB21.2 KiB0 B (0.0%)29.3 KiB✅
ClaudeLive turn messages220 (0.0%)8✅

Baseline: 159f2b8 · PR result: 26c41f4 · Source CI: failure

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. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 87d35d61-838e-43b7-b429-4072849f9263
📥 Commits

Reviewing files that changed from the base of the PR and between 2333f168845f853f9ef358d1c4e6cf75189f4e8b and 26c41f4c7fa8721d1fa2fee9b4de2e026e049ac8.

📒 Files selected for processing: 5
  • apps/server/src/provider/ClaudeProvider.ts
  • apps/server/src/provider/Drivers/ClaudeDriver.ts
  • apps/server/src/provider/ProviderRegistry.test.ts
  • apps/server/src/provider/ProviderRegistry.ts
  • packages/provider-core/src/server/driver.ts

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

📝 Walkthrough

Claude workspace scans now publish discovered skills before slash-command probing completes. The provider registry then publishes the final snapshot and retains ownership checks for partial and final updates.

Changes: Workspace snapshot updates

Layer / File(s)Summary
Claude partial snapshot callback
packages/provider-core/src/server/driver.ts, apps/server/src/provider/Drivers/ClaudeDriver.ts, apps/server/src/provider/ClaudeProvider.ts
The driver accepts and forwards an optional partial-publication callback. Claude probing calls it after skill discovery with slash-command discovery marked pending.
Registry snapshot updates
apps/server/src/provider/ProviderRegistry.ts, apps/server/src/provider/ProviderRegistry.test.ts
The registry publishes partial and final results through an ownership-checked path. The integration test verifies that discovered skills are published before slow command probing finishes, then checks the final command result.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

mermaid
1sequenceDiagram
2 participant ProviderRegistry
3 participant ClaudeDriver
4 participant ClaudeProvider
5 ProviderRegistry->>ClaudeDriver: Start snapshotForCwd with publishPartial
6 ClaudeDriver->>ClaudeProvider: Probe workspace with publishPartial
7 ClaudeProvider->>ProviderRegistry: Publish skills with slashCommandsPending true
8 ClaudeProvider-->>ClaudeDriver: Return final workspace snapshot
9 ClaudeDriver-->>ProviderRegistry: Return final workspace snapshot

Suggested reviewers: maria-rcks, t3dotgg

Merge Risk: ⚪ Minimal · up to 26c41

Workspace skills can appear before command discovery completes, without an established issue that needs correction before merge.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main change: showing Claude project skills before command discovery completes.
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Description checkPassedThe pull request description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the defect, implementation, issue reference, approval context, focused t…
Full details: Description check

Explanation

The pull request description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the defect, implementation, issue reference, approval context, focused tests, observed results, limitations, and agent details. The description is complete and relevant.

✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
📝 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.