-
Notifications
You must be signed in to change notification settings - Fork 153
fixed wrong reusage of checkpoint id for multiple commits #268
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -380,23 +380,15 @@ func (s *ManualCommitStrategy) PrepareCommitMsg(commitMsgFile string, source str | |
| } | ||
|
|
||
| if hasNewContent { | ||
| // New content: check PendingCheckpointID first (set during previous condensation), | ||
| // otherwise generate a new one. This ensures idempotent IDs across hook invocations. | ||
| for _, state := range sessionsWithContent { | ||
| if state.PendingCheckpointID != "" { | ||
| if cpID, err := id.NewCheckpointID(state.PendingCheckpointID); err == nil { | ||
| checkpointID = cpID | ||
| break | ||
| } | ||
| } | ||
| } | ||
| if checkpointID.IsEmpty() { | ||
| cpID, err := id.Generate() | ||
| if err != nil { | ||
| return fmt.Errorf("failed to generate checkpoint ID: %w", err) | ||
| } | ||
| checkpointID = cpID | ||
| // New content: generate a fresh checkpoint ID. | ||
| // Idempotency for hook re-runs is handled by the trailer existence check above. | ||
| // NOTE: Do NOT reuse PendingCheckpointID here - it's from a previous commit's | ||
| // PostCommit and would cause duplicate IDs across different commits. | ||
| cpID, err := id.Generate() | ||
| if err != nil { | ||
| return fmt.Errorf("failed to generate checkpoint ID: %w", err) | ||
| } | ||
| checkpointID = cpID | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Message commits skip confirmation unexpectedlyMedium Severity After switching to fresh IDs, Additional Locations (1)
Comment on lines
+383
to
+391
|
||
| } | ||
| // Otherwise checkpointID is already set to LastCheckpointID from above | ||
|
|
||
|
|
@@ -1068,35 +1060,26 @@ func (s *ManualCommitStrategy) sessionHasNewContentFromLiveTranscript(repo *git. | |
| // (ACTIVE session + no TTY). Generates a checkpoint ID and adds the trailer | ||
| // directly, bypassing content detection and interactive prompts. | ||
| func (s *ManualCommitStrategy) addTrailerForAgentCommit(logCtx context.Context, commitMsgFile string, state *SessionState, source string) error { | ||
| // Use PendingCheckpointID if set, otherwise generate a new one | ||
| var cpID id.CheckpointID | ||
| if state.PendingCheckpointID != "" { | ||
| var err error | ||
| cpID, err = id.NewCheckpointID(state.PendingCheckpointID) | ||
| if err != nil { | ||
| cpID = "" // fall through to generate | ||
| } | ||
| } | ||
| if cpID.IsEmpty() { | ||
| var err error | ||
| cpID, err = id.Generate() | ||
| if err != nil { | ||
| return nil //nolint:nilerr // Hook must be silent on failure | ||
| } | ||
| } | ||
|
|
||
| content, err := os.ReadFile(commitMsgFile) //nolint:gosec // commitMsgFile is provided by git hook | ||
| if err != nil { | ||
| return nil //nolint:nilerr // Hook must be silent on failure | ||
| } | ||
|
|
||
| message := string(content) | ||
|
|
||
| // Don't add if trailer already exists | ||
| // Don't add if trailer already exists (idempotency for hook re-runs) | ||
| if _, found := trailers.ParseCheckpoint(message); found { | ||
| return nil | ||
| } | ||
|
|
||
| // Generate a fresh checkpoint ID. | ||
| // NOTE: Do NOT reuse PendingCheckpointID here - it's from a previous commit's | ||
| // PostCommit and would cause duplicate IDs across different commits. | ||
| cpID, err := id.Generate() | ||
| if err != nil { | ||
| return nil //nolint:nilerr // Hook must be silent on failure | ||
| } | ||
|
|
||
| message = addCheckpointTrailer(message, cpID) | ||
|
|
||
| logging.Info(logCtx, "prepare-commit-msg: agent commit trailer added", | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -166,6 +166,38 @@ Location: `.git/entire-sessions/<session-id>.json` | |||||
|
|
||||||
| Stored in git common dir (shared across worktrees). Tracks active session info. | ||||||
|
|
||||||
| #### Checkpoint ID Fields | ||||||
|
|
||||||
| Two checkpoint ID fields in session state track different lifecycle stages: | ||||||
|
|
||||||
| | Field | Set By | Cleared By | Purpose | | ||||||
| |-------|--------|------------|---------| | ||||||
| | `PendingCheckpointID` | PostCommit (ACTIVE → ACTIVE_COMMITTED) | `condenseAndUpdateState` | Deferred condensation coordination | | ||||||
| | `LastCheckpointID` | `condenseAndUpdateState` | `InitializeSession` (new prompt) | Amend trailer restoration | | ||||||
|
||||||
| | `LastCheckpointID` | `condenseAndUpdateState` | `InitializeSession` (new prompt) | Amend trailer restoration | | |
| | `LastCheckpointID` | `condenseAndUpdateState` | `InitializeSession` (new prompt) | Amend trailer restoration and reusing/linking an existing condensed checkpoint when new commits have no additional content (e.g., manual-commit strategy) | |


There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Earlier commit IDs become unreachable
High Severity
PrepareCommitMsgnow always generates a new checkpoint ID for new content, but session state still keeps only onePendingCheckpointID. In multi-commit active turns, laterPostCommitcalls overwrite earlier IDs, and turn-end condensation uses only the last one. Earlier commits keep trailers pointing to checkpoint IDs that never get condensed.Additional Locations (2)
cmd/entire/cli/strategy/manual_commit_hooks.go#L706-L707cmd/entire/cli/strategy/manual_commit_hooks.go#L1479-L1486