[GH-ISSUE #193] AI Checkpoint Incorrectly Claims Human Lines When AI deletes it's own lines #78

Closed
opened 2026-03-02 04:11:40 +03:00 by kerem · 2 comments
Owner

Originally created by @AtnesNess on GitHub (Nov 6, 2025).
Original GitHub issue: https://github.com/git-ai-project/git-ai/issues/193

Originally assigned to: @svarlamov on GitHub.

Description

When a human checkpoint and an AI checkpoint occur sequentially in the same commit, and the AI checkpoint deletes one of its own lines from a previous commit, the AI checkpoint incorrectly attributes all human additions as AI additions.

Expected Behavior

When both human and AI modify a file in the same commit:

  1. Human checkpoint tracks human additions
  2. AI checkpoint tracks only AI additions/deletions
  3. Stats correctly show: human_additions: 2, ai_additions: 2, ai_accepted: 2

Actual Behavior

The AI checkpoint claims all lines added in the commit, including those from the human checkpoint:

  • human_additions: 0 (should be 2)
  • ai_additions: 4 (should be 2)
  • ai_accepted: 4 (should be 2)

Steps to Reproduce

# COMMIT 1: AI creates initial content
cat > data.txt <<'EOF'
Base Line 1
Base Line 2
AI: Line 1
AI: Line 2
AI: Line 3
Base Line 3
EOF
git-ai checkpoint mock_ai data.txt
git add data.txt
git commit -m "Commit 1: AI adds 3 lines"

# COMMIT 2: Human adds 2 lines, then AI modifies
# Step 1: Human adds lines
cat > data.txt <<'EOF'
Base Line 1
Base Line 2
AI: Line 1
AI: Line 2
AI: Line 3
Human: Line 1
Human: Line 2
Base Line 3
EOF
git-ai checkpoint  # Human checkpoint

# Step 2: AI deletes one of its own lines and adds 2 new lines
cat > data.txt <<'EOF'
Base Line 1
Base Line 2
AI: Line 1
AI: Line 3
Human: Line 1
Human: Line 2
AI: New Line 1
AI: New Line 2
Base Line 3
EOF
git-ai checkpoint mock_ai data.txt  # AI checkpoint

git add data.txt
git commit -m "Commit 2: Human adds 2, AI deletes 1 and adds 2"

# Check stats
git-ai stats HEAD --json

Actual Output

{
  "human_additions": 0,
  "ai_additions": 4,
  "ai_accepted": 4,
  "total_ai_additions": 2,
  "total_ai_deletions": 1
}

Expected Output

{
  "human_additions": 2,
  "ai_additions": 2,
  "ai_accepted": 2,
  "total_ai_additions": 2,
  "total_ai_deletions": 1
}

Test Case

A failing test case has been added: "Attribution is correct after AI deleted it's own lines from previous commit"

Location: tests/e2e/user-scenarios.bats

The test is currently skipped with a reference to this issue.

Context

This bug specifically occurs when:

  1. Both human and AI checkpoints happen in the same commit
  2. The AI checkpoint performs deletions (especially of its own previous lines)
  3. The AI checkpoint runs after the human checkpoint
Originally created by @AtnesNess on GitHub (Nov 6, 2025). Original GitHub issue: https://github.com/git-ai-project/git-ai/issues/193 Originally assigned to: @svarlamov on GitHub. ## Description When a human checkpoint and an AI checkpoint occur sequentially in the same commit, and the AI checkpoint deletes one of its own lines from a previous commit, the AI checkpoint incorrectly attributes **all human additions** as AI additions. ## Expected Behavior When both human and AI modify a file in the same commit: 1. Human checkpoint tracks human additions 2. AI checkpoint tracks only AI additions/deletions 3. Stats correctly show: `human_additions: 2, ai_additions: 2, ai_accepted: 2` ## Actual Behavior The AI checkpoint claims all lines added in the commit, including those from the human checkpoint: - `human_additions: 0` ❌ (should be 2) - `ai_additions: 4` ❌ (should be 2) - `ai_accepted: 4` ❌ (should be 2) ## Steps to Reproduce ```bash # COMMIT 1: AI creates initial content cat > data.txt <<'EOF' Base Line 1 Base Line 2 AI: Line 1 AI: Line 2 AI: Line 3 Base Line 3 EOF git-ai checkpoint mock_ai data.txt git add data.txt git commit -m "Commit 1: AI adds 3 lines" # COMMIT 2: Human adds 2 lines, then AI modifies # Step 1: Human adds lines cat > data.txt <<'EOF' Base Line 1 Base Line 2 AI: Line 1 AI: Line 2 AI: Line 3 Human: Line 1 Human: Line 2 Base Line 3 EOF git-ai checkpoint # Human checkpoint # Step 2: AI deletes one of its own lines and adds 2 new lines cat > data.txt <<'EOF' Base Line 1 Base Line 2 AI: Line 1 AI: Line 3 Human: Line 1 Human: Line 2 AI: New Line 1 AI: New Line 2 Base Line 3 EOF git-ai checkpoint mock_ai data.txt # AI checkpoint git add data.txt git commit -m "Commit 2: Human adds 2, AI deletes 1 and adds 2" # Check stats git-ai stats HEAD --json ``` ## Actual Output ```json { "human_additions": 0, "ai_additions": 4, "ai_accepted": 4, "total_ai_additions": 2, "total_ai_deletions": 1 } ``` ## Expected Output ```json { "human_additions": 2, "ai_additions": 2, "ai_accepted": 2, "total_ai_additions": 2, "total_ai_deletions": 1 } ``` ## Test Case A failing test case has been added: `"Attribution is correct after AI deleted it's own lines from previous commit"` Location: `tests/e2e/user-scenarios.bats` The test is currently skipped with a reference to this issue. ## Context This bug specifically occurs when: 1. Both human and AI checkpoints happen in the same commit 2. The AI checkpoint performs deletions (especially of its own previous lines) 3. The AI checkpoint runs **after** the human checkpoint
kerem closed this issue 2026-03-02 04:11:41 +03:00
Author
Owner

@AtnesNess commented on GitHub (Nov 6, 2025):

See test in https://github.com/acunniffe/git-ai/pull/194

<!-- gh-comment-id:3499310035 --> @AtnesNess commented on GitHub (Nov 6, 2025): See test in https://github.com/acunniffe/git-ai/pull/194
Author
Owner

@acunniffe commented on GitHub (Nov 7, 2025):

@svarlamov I went in to verify that the checkpoints were working right (look good!). I think this is being caused by SUPER greedy DMP after line deletion.

checkpoint: "\n========== CHECKPOINT DEBUG: data.txt ==========\nCheckpoint Kind: AiAgent\nAuthor ID: 45b9075\nSource: Previous checkpoint\n\n--- PREVIOUS CONTENT (blob/checkpoint) ---\nBase Line 1\nBase Line 2\nAI: Line 1\nAI: Line 2\nAI: Line 3\nHuman: Line 1\nHuman: Line 2\nBase Line 3\n\n--- CURRENT CONTENT (filesystem) ---\nBase Line 1\nBase Line 2\nAI: Line 1\nAI: Line 3\nHuman: Line 1\nHuman: Line 2\nAI: New Line 1\nAI: New Line 2\nBase Line 3\n\n--- PREVIOUS ATTRIBUTIONS ---\n[Attribution { start: 0, end: 24, author_id: \"human\", ts: 1762521087015 }, Attribution { start: 24, end: 35, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 35, end: 46, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 46, end: 57, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 57, end: 85, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 85, end: 96, author_id: \"human\", ts: 1762521087015 

Some of these are cutting cut into 1-2 char attributions, getting mixed with AI lines, and then getting marked as a line dominated by AI code. I tried not deleting the line and the problem went away (as @AtnesNess said in the title).

}]\n==========================================\n\n>>> make_entry_for_file: data.txt (author: 45b9075)\n>>> Filled in previous attributions: [Attribution { start: 0, end: 24, author_id: \"human\", ts: 1762521087015 }, Attribution { start: 24, end: 35, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 35, end: 46, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 46, end: 57, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 57, end: 85, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 85, end: 96, author_id: \"human\", ts: 1762521087015 }]\n>>> New attributions after update: [Attribution { start: 0, end: 24, author_id: \"human\", ts: 1762521087015 }, Attribution { start: 24, end: 35, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 35, end: 44, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 44, end: 45, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 45, end: 46, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 46, end: 51, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 51, end: 58, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 58, end: 59, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 59, end: 60, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 60, end: 72, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 72, end: 87, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 87, end: 89, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 89, end: 91, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 91, end: 92, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 92, end: 96, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 96, end: 104, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 104, end: 115, author_id: \"human\", ts: 1762521087015 }]\n>>> Line attributions: [LineAttribution { start_line: 3, end_line: 3, author_id: \"6d8cc49\", overrode: None }, LineAttribution { start_line: 4, end_line: 8, author_id: \"45b9075\", overrode: None }]\nai_agent mock_ai changed 1 file(s) that have changed since the last commit\nCheckpoint completed in 36.853125ms\n"

I'm going to add my tests to https://github.com/acunniffe/git-ai/pull/194 so you have a starting point in the repo and assign this one to you

<!-- gh-comment-id:3502500762 --> @acunniffe commented on GitHub (Nov 7, 2025): @svarlamov I went in to verify that the checkpoints were working right (look good!). I think this is being caused by SUPER greedy DMP after line deletion. ``` checkpoint: "\n========== CHECKPOINT DEBUG: data.txt ==========\nCheckpoint Kind: AiAgent\nAuthor ID: 45b9075\nSource: Previous checkpoint\n\n--- PREVIOUS CONTENT (blob/checkpoint) ---\nBase Line 1\nBase Line 2\nAI: Line 1\nAI: Line 2\nAI: Line 3\nHuman: Line 1\nHuman: Line 2\nBase Line 3\n\n--- CURRENT CONTENT (filesystem) ---\nBase Line 1\nBase Line 2\nAI: Line 1\nAI: Line 3\nHuman: Line 1\nHuman: Line 2\nAI: New Line 1\nAI: New Line 2\nBase Line 3\n\n--- PREVIOUS ATTRIBUTIONS ---\n[Attribution { start: 0, end: 24, author_id: \"human\", ts: 1762521087015 }, Attribution { start: 24, end: 35, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 35, end: 46, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 46, end: 57, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 57, end: 85, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 85, end: 96, author_id: \"human\", ts: 1762521087015 ``` Some of these are cutting cut into 1-2 char attributions, getting mixed with AI lines, and then getting marked as a line dominated by AI code. I tried not deleting the line and the problem went away (as @AtnesNess said in the title). ``` }]\n==========================================\n\n>>> make_entry_for_file: data.txt (author: 45b9075)\n>>> Filled in previous attributions: [Attribution { start: 0, end: 24, author_id: \"human\", ts: 1762521087015 }, Attribution { start: 24, end: 35, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 35, end: 46, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 46, end: 57, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 57, end: 85, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 85, end: 96, author_id: \"human\", ts: 1762521087015 }]\n>>> New attributions after update: [Attribution { start: 0, end: 24, author_id: \"human\", ts: 1762521087015 }, Attribution { start: 24, end: 35, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 35, end: 44, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 44, end: 45, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 45, end: 46, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 46, end: 51, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 51, end: 58, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 58, end: 59, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 59, end: 60, author_id: \"6d8cc49\", ts: 1762521087016 }, Attribution { start: 60, end: 72, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 72, end: 87, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 87, end: 89, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 89, end: 91, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 91, end: 92, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 92, end: 96, author_id: \"45b9075\", ts: 1762521087125 }, Attribution { start: 96, end: 104, author_id: \"human\", ts: 1762521087016 }, Attribution { start: 104, end: 115, author_id: \"human\", ts: 1762521087015 }]\n>>> Line attributions: [LineAttribution { start_line: 3, end_line: 3, author_id: \"6d8cc49\", overrode: None }, LineAttribution { start_line: 4, end_line: 8, author_id: \"45b9075\", overrode: None }]\nai_agent mock_ai changed 1 file(s) that have changed since the last commit\nCheckpoint completed in 36.853125ms\n" ``` I'm going to add my tests to https://github.com/acunniffe/git-ai/pull/194 so you have a starting point in the repo and assign this one to you
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/git-ai#78
No description provided.