Repository navigation
Conversation
|
Important Review skippedWe couldn't safely recover the incremental review. No full review was started, and the last reviewed checkpoint was preserved. Retry later, or explicitly request a full review by commenting You can disable this status message by setting the Use the checkbox below for a quick retry:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughCheckpoint capture now writes new Git objects to a temporary quarantine in the repository object directory. It publishes recognized objects before updating the checkpoint ref, then removes the quarantine. Tests cover concurrent captures, publication failures, interruption, and timeout. ChangesCheckpoint capture storage
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant GitVcsDriver
participant Quarantine
participant ObjectDirectory
participant CheckpointRef
GitVcsDriver->>Quarantine: Capture Git objects
GitVcsDriver->>ObjectDirectory: Publish loose objects and pack components
GitVcsDriver->>CheckpointRef: Update checkpoint ref
GitVcsDriver->>Quarantine: Remove quarantine
Suggested reviewers: Merge Risk: ⚪ Minimal · up to Checkpoint capture now writes new Git objects to a temporary quarantine and removes it on failure, timeout or interruption. Objects are published before the checkpoint ref is updated, and the tests cover the failure paths. One narrow race in the rename fallback is documented by the author and is not a merge blocker. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to The change substantially improves cleanup after failed captures. However, overlapping captures combined with a publication failure can remove a pack another capture needs, compromising checkpoint recovery. Normal same-workspace operations are serialized, which limits exposure, but that protection is not repository-wide. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…ck-leak # Conflicts: # apps/server/src/vcs/GitVcsDriver.ts
Fixes the remaining case from #3646 (comment).
Problem
Checkpoint capture runs
git add -Awith a private index, but Git still writes new objects into the repository's shared object store. An untracked file larger thancore.bigFileThresholdis streamed straight into.git/objects/pack/tmp_pack_*. When the 30 second VCS timeout killsgit add, that temporary pack stays behind, and every later turn adds another one. Users reported 82 GB and 380 GB of abandoned packs.Fix
Each capture now writes its objects to a private directory,
<objects>/tmp_objdir-t3-checkpoint-<uuid>, throughGIT_OBJECT_DIRECTORY, and reads existing objects from the real store throughGIT_ALTERNATE_OBJECT_DIRECTORIES. This is the same quarantinegit receive-packuses. The private index lives in that directory too.update-ref. It never replaces an existing object and publishes each pack before its index, the order Git uses for its own quarantine. Both steps are quick and run uninterruptibly, so an interruption cannot strand a pack. If publication itself fails (for example on a full disk), the files of any pack whose index was not published yet are removed again, because Git ignores a pack without its index andgcnever removes one. A pack whose index is published stays, since another capture may already use it;gcreclaims it if nothing does.gcremoves the leftovertmp_objdir-*directory once it is two weeks old.Limits: if a capture's pack publication fails in the same instant another capture is publishing a byte-identical pack, the other capture can lose its pack; this needs a disk error plus identical concurrent work within milliseconds. A
git prunewithout--expirerun by the user mid-capture deletes the live quarantine and fails that capture, the same race the old code had ontmp_pack_*. Windows was reasoned about (;delimiter, backslash quoting, NTFS hard links) but not executed; server tests run on Linux only.Out of scope, and unchanged: a capture over a huge file still times out every turn, so the CPU cost and the "missing checkpoint" result remain. That needs a separate policy decision.
Relation to #15297: that PR skips untracked files over 100 MiB, which changes what checkpoints capture and restore. This PR changes no behavior; it makes every killed or interrupted capture leave nothing behind, including timeouts from large repos, slow or network disks, and files under any size cap. The two are complementary.
Proof
Real server, real Claude turns. Fresh T3 home, disposable repo with one tracked file and one untracked 2 GiB incompressible file, two
claude-sonnet-5-5turns through the WebSocket API:maintmp_pack_*after turn 1 / turn 2git count-objectsgarbagegit fsck --strictProduction capture function, no mocks. The reporter's probe (real
GitVcsDriver,VcsProcess, 30 s timeout):mainA planted foreign
tmp_pack_*survived every run, and the real index andHEADnever changed.Scripts and raw JSON for both runs: t3-3646-evidence.zip.
Tests (
GitVcsDriver.test.ts, real Git, no sleeps):git addwhile the large file's pack is open, then the capture is interrupted, and separately times out through the real 30 s path. The object store listing is unchanged, a concurrent command'stmp_pack_*and another capture's quarantine survive, existing refs and the real index are intact, and a later capture stores the file correctly. Fails onmainwith a leftoverpack/tmp_pack_*..packbehind, and one that fails on a later loose object keeps the complete pack readable. Both cases were found in review and reproduced before being fixed.fsck --strictpasses, and new object directories keepcore.sharedRepositorypermissions. Fails if the permission copy is removed.Fixes #3646
Made with Claude Opus 5.5 in Claude Code, running in T3 Code. Design iterated with Claude Fable 5.1 and GPT 6.0 Astra; code reviewed by both.