feat(import): anchor imported checkpoints to the default branch head#1825
Merged
Conversation
Adds WriteOptions.CommitSHA, persisted as commit_sha on both the session Metadata and root CheckpointSummary (omitempty, so non-import writers stay byte-identical). agentimport.Options gains LinkCommitSHA, copied verbatim into each imported turn's WriteOptions.CommitSHA; resolution of the actual SHA is left to a later task. Entire-Checkpoint: 01KY33NAEBCQFV87TK2QZM2XYD
Adds resolveImportLinkCommitSHA, which resolves the commit imported checkpoints stamp as commit_sha: origin's tip of the default branch (the commit the server already knows) preferred over the local branch tip, then HEAD, then empty when nothing resolves. Wires it into `entire import <agent>` via agentimport.Options.LinkCommitSHA. Entire-Checkpoint: 01KY34D8R1WQXZCK1TV9T2RXHX
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an optional commit_sha anchor to checkpoints produced by entire import, linking imported (commit-less) history to the default branch head at import time so downstream UI/services can immediately join imported sessions to a repo/commit context without rewriting git history.
Changes:
- Thread
commit_shathrough import (resolveImportLinkCommitSHA→agentimport.Options.LinkCommitSHA→ checkpointWriteOptions.CommitSHA). - Persist
commit_shaon both per-sessionmetadata.jsonand rootCheckpointSummary(with preserve-on-rewrite behavior added for the root summary). - Add unit tests and update architecture docs describing the new import anchoring behavior.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| docs/architecture/sessions-and-checkpoints.md | Documents commit_sha behavior for imported checkpoints and resolution precedence. |
| cmd/entire/cli/import_link.go | Implements best-effort default-branch/HEAD commit SHA resolution for import anchoring. |
| cmd/entire/cli/import_link_test.go | Adds unit coverage for origin-vs-local preference, HEAD fallback, and empty repo behavior. |
| cmd/entire/cli/import_cmd.go | Wires resolved LinkCommitSHA into the import runner options. |
| cmd/entire/cli/checkpoint/persistent.go | Persists CommitSHA into session metadata + root summary; root summary preserves existing value on rewrite. |
| cmd/entire/cli/checkpoint/persistent_imported_test.go | Verifies persistence + omitempty behavior for commit_sha in imported checkpoints. |
| cmd/entire/cli/agentimport/agentimport.go | Threads LinkCommitSHA through to each imported checkpoint write. |
| cmd/entire/cli/agentimport/agentimport_test.go | Tests that LinkCommitSHA is stamped (and omitted when unset). |
| api/checkpoint/metadata.go | Adds CommitSHA fields to WriteOptions, session Metadata, and root CheckpointSummary. |
… in tests Addresses toolkit review findings on #1825: a Debug line records the resolved anchor (support can tell why an import is unanchored or stale), an integration assertion pins the import_cmd wiring end to end (omitempty would otherwise hide a dropped wire), a store test covers the summary preserve-on-rewrite branch, and comment polish (canonical CommitSHA doc on WriteOptions, softened default-branch over-claims). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KY39WXXNWBZ6SQQDE9TMJWN8
Retest caught that logging.Debug is a no-op without logging.Init; import never called it, making the just-added anchor log dead code. Init best-effort like explain/resume. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KY3A8RAG6E2BFNVZZZYWTGNR
computermode
previously approved these changes
Jul 22, 2026
Extends the import commit_sha anchor (PR #1825) to be per-turn: when a Claude Code transcript records the commit(s) a turn made via gitOperation records, the turn's checkpoint anchors to the last such commit that resolves and is an ancestor of the default-branch fallback, instead of always pointing at the default-branch head. Older transcripts (or recorded commits that were squashed/rebased away) keep the existing fallback behavior unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KY5P3CT3T2K4KGK4QCTBGMA6
Thread ctx through turnAnchorResolver so both ancestor-walk failure paths and per-turn fallback decisions are Debug-logged — import is one-shot, so an unlogged fallback destroys the only evidence of why a turn didn't anchor to its recorded commit. Adds a regression test for a well-formed but nonexistent fallback (no panic, graceful degrade) and a garbage-line resilience test for commit-SHA extraction. Corrects several comments that overstated go-git's ambiguity detection, referenced code that never existed, or were Claude-specific where the type is agent-generic. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KY7JCMV9PHB2XSQ3G71809Q1
pjbgf
reviewed
Jul 23, 2026
Addresses pjbgf's PR comment and the matching trail finding: the memoized ancestor walk was a full-history traversal with unbounded memory. It now emits newest-first (committer-time order) and stops at commits older than the lookback window plus slack, or at 50k commits — committer-time ordering is what makes early-stopping sound where a DFS could not. Also makes resolve report whether a candidate actually won, so the fell-back debug log no longer fires when a turn's recorded commit IS the tip (second trail finding). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Entire-Checkpoint: 01KY7PMXSPJ34221FYN8PEWRQ1
pjbgf
approved these changes
Jul 23, 2026
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/entireio/cli/trails/916
What
entire importnow stamps acommit_shafield into every checkpoint it writes — the default branch's head at import time (origin tip preferred → local branch → HEAD → empty). It lands in both the sessionmetadata.jsonand the rootCheckpointSummary(omitempty, preserve-on-rewrite), giving the UI a join key to anchor imported sessions to a commit so repo pages and stats populate immediately after an import.Why
Imported history is commit-less: the normal commit↔checkpoint join is the
Entire-Checkpointtrailer, which pre-existing commits don't have and never will (we don't rewrite history). The anchor is deliberately a link, not attribution — it says "imported at this point in time", not "this session built that commit". The sha lives inside the checkpoint metadata rather than in a ref name: checkpoint IDs are strictly 12-hex/ULID, and stuffing a 40-hex sha intorefs/entire/checkpoints/would break ID validation and force a growing shared-ref list for the common all-anchors-same-sha case.How
WriteOptions.CommitSHA→ sessionMetadata+ rootCheckpointSummary(commit_sha, omitempty; root summary preserves a stamped value if a later write carries an empty one, mirroring the existingImported/HasReviewpattern)agentimport.Options.LinkCommitSHAthreaded throughRun→writeTurn; resolution stays out of the packageresolveImportLinkCommitSHAin theclipackage: origin's default-branch tip (the commit the server already knows) → local branch → HEAD →""(best-effort; an unresolvable repo imports unlinked, never fails)Per-turn real-commit anchors
When a Claude Code transcript records the commits a turn made (
toolUseResult.gitOperation.commit, kindcommitted), that turn's checkpoint anchors to the real commit instead of the head anchor: the recorded (short) sha is resolved, must be an ancestor of the default-branch tip (ancestry doubles as the reachability check — squash-merged/rebased-away commits fall through), and the last such commit of the turn wins. Everything else — older transcripts without the records, unresolvable or unreachable shas — falls back to the default-branch-head anchor above. The fallback's ancestor set is memoized lazily (one history walk per import run). Samecommit_shafield either way; consumers see no schema difference.Testing
origin/mainvs localmain) and coverage of the HEAD-fallback and empty-repo armscommit_shapresent and correct in both, idempotent re-import leaves it untouched/etrepo, real transcript, full enable→import→push flow): refs withcommit_sharound-trip through the server intact. Control experiment confirmed server ingestion is currently trailer-driven: a normal checkpoint ingested into/me/recapin ~2 min while the imported refs (on the server,commit_shaand all) were never indexed.Notes for reviewers
Metadata/CheckpointSummaryare not schema-versioned, so an older CLI that rewrites an existing checkpoint (OPF pre-push re-redaction, compact-marker update, multi-session summary rebuild) round-trips through structs withoutcommit_shaand silently drops it. This is the same exposure every additive metadata field has had; the existing fence is the checkpoint policy ref (checkpoint_min_version). Practical blast radius for imported checkpoints is narrow — attribution never targets them and rewind/generate are blocked.Out of scope / follow-ups
commit_sha(kindimported) and join on that field; render imported sessions as anchored to the commit, not attributed to it. The smoke test above is the repro.fsstorebackend doesn't map the new field (consistent with it already skippingImported).🤖 Generated with Claude Code
Note
Low Risk
Additive metadata and best-effort import resolution; no changes to normal checkpoint writes or git history rewriting.
Overview
Adds an optional
commit_shafield on checkpointWriteOptions, sessionMetadata, and rootCheckpointSummaryso imported history can be tied to a git commit without anEntire-Checkpointtrailer.entire importnow resolves a link SHA at the CLI (resolveImportLinkCommitSHA:origin/<default>→ local default branch →HEAD→"") and passes it throughagentimport.Options.LinkCommitSHAinto each imported turn. The anchor is display-only (“imported at this point”), not attribution; import still succeeds when resolution fails.The persistent git store persists
commit_shaon session metadata and the root summary, withomitemptyand preserve-on-rewrite when a later write leaves it empty (same pattern asImported/HasReview). Architecture docs describe the field; tests cover resolver preference, import stamping, and persistence.Reviewed by Cursor Bugbot for commit d2df272. Configure here.