fix: repair stale checkpoints and flag worktree setup gaps - #7
Draft
MuskanPaliwal wants to merge 7 commits into
Draft
MuskanPaliwal wants to merge 7 commits into
MuskanPaliwal wants to merge 7 commits into
Conversation
CLI versions before v0.10.1 walked nested git checkouts (Claude Code's .claude/worktrees/) into prompt_attributions.user_added_per_file on every prompt, producing 70MB and 106MB per-session metadata.json blobs on entire/checkpoints/v1. GitHub refuses blobs over 100 MiB, so one such blob anywhere in the branch history makes it unpushable and unmirrorable there (customer report, T-88). The v0.10.1 fix stopped new bloat but left the history behind, and the only remedy was a hand-written filter-repo script. Prevention: checkpoint.CapPromptAttributions drops the field above 4 MiB at the checkpoint write boundary (both writers). Nothing reads the field back and entire-api's ingest already salvages a metadata.json clipped at it. Repair: `entire doctor` gains a "Checkpoint metadata size" check that scans the branch (and the elected sync remote's tracking ref) for metadata.json blobs over 50 MiB and offers to rewrite the branch without the field, then force-push it with --force-with-lease against the observed tip. Commit messages, authors, dates, checkpoint IDs and every other blob are preserved; history before the first oversized blob keeps its hashes. `doctor --force` deliberately does not apply it (it rewrites history and pushes); the opt-in is an interactive yes or `entire doctor shrink-checkpoint-metadata [--yes]`. Reconciliation is by content, not hash: local is rewritten before the remote is reconciled with the same memoized rewriter, and the rewritten tips are compared by tree, so an independently repaired clone (or commit signing, which makes rewritten hashes differ) is adopted rather than replayed as duplicates. A dedicated checkpoint_remote URL is report-only. The repair is per clone and says so. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
TestHashComparisonsUseEqual flagged `newEntry.Hash != e.Hash`. Every hash comparison in metadata_shrink.go now goes through Hash.Equal, including the ones the textual guard does not reach: plumbing.Hash carries an object-format field alongside the bytes, so == can disagree with Equal on a sha256 repo. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Decide the dedicated checkpoint_remote case before the no-remote early return, so a repository whose only checkpoint destination is that URL is refused the repair consistently. Settings are read for the repository the scan was handed (new settings.LoadForWorktreeRoot), not the process cwd. - Apply the prompt_attributions cap in updateSessionMetadata too: the finalize/backfill path re-marshals metadata an older CLI wrote and would otherwise copy a pre-cap field into every later rewrite. - Writer-level tests for the cap on both the fresh write and the re-marshal path, in addition to the helper unit tests. - Report the remote as unverified instead of printing OK when its tracking ref could not be read. - Distinguish the 50 MiB warning threshold from GitHub's 100 MiB hard limit in the report; only files over the hard limit make the branch unpushable. - Open test repositories through gitrepo.OpenPath, per repo convention. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Entire-Checkpoint: 01M2DSN65JETVT9YY8T4ABW2J5
Entire-Checkpoint: 01M2FNRCE1AMZZVN8C15DVKP6S
…ckpoint-metadata # Conflicts: # CLAUDE.md # cmd/entire/cli/doctor.go
Entire-Checkpoint: 01M2SP2J7Z3PW4XVMHV24HDTMG
MuskanPaliwal
pushed a commit
that referenced
this pull request
Sep 24, 2026
…ionFile #5 external.go reimplemented SessionStore.Name's relative branch verbatim — same IsAbs/VolumeName pairing, same ToSlash(Clean(FromSlash(…))) — without the comment explaining why the pairing is needed, and it had to know that the store checks a name only after Name has produced one, which is WriteFile's private prologue. Name's relative branch is now a named primitive both callers share, the store exposes ValidateExternalSessionRef (every rule needing no store, plus whether the ref is filesystem-shaped) and ValidateExternalWriteRef (the store-backed half), and ValidateWritePath is unexported. #6 The preflight ran after marshalling and was gated as a whole on RepoPath != "". Both current callers set RepoPath, which is what makes that a check that disappears silently for the next one; the lexical rules need no repo, so only the store-backed half is conditional now. The remaining asymmetry — an opaque relative ref is forwarded as given while an absolute one is resolved — is the protocol's, not this function's, and is left alone deliberately. #7 ErrOutsideSessionStore said "path is outside the agent's session directory" for an ID that never resolved anywhere, which names the wrong problem. Malformed names now report ErrUnsafeSessionName; a path that genuinely left the store still reports ErrOutsideSessionStore. validateWriteName no longer claims to "inspect" anything — it touches no filesystem. #8 The volume-separator check existed in both validators, worded identically, while the shared reason helper omitted it. It moves in. ValidateSessionID keeps its separator check ahead of the helper so a Windows absolute path still reports the separators rather than the colon. The ResolveSessionFile contract this branch wrote into agent.go had two live violations: copilotcli's resolveTranscriptRef and cursor's, both passing a raw payload ID to a resolver that puts it in a directory position. Both now resolve through SessionStore.SessionFile, and a GitGrepGuard fails the build on the next one. Two guards in buildAgentStop go: isSubagentAgentStop already returns false for an unsafe ID via SessionFile, and ExtractModelFromTranscript reads a path and never touches the ID, so gating it only dropped model attribution. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 01M2RM92E1D4CK1JJ6NDSMTMHC
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
https://entire.io/gh/MuskanPaliwal/cli/trails/7
Trail: https://entire.io/gh/MuskanPaliwal/cli/trails/6 — Upstream PR: entireio#2408