Count checkpoint "steps" by prompts, not file-modifying turns#1347
Count checkpoint "steps" by prompts, not file-modifying turns#1347dipree wants to merge 6 commits into
Conversation
The session "steps" shown in the UI came from the CLI's StepCount, which only incremented on turns that modified files and reset to 0 after each condensation. This produced wrong and frequently-zero counts. - Bug 1: checkpoints written before any SaveStep ran (mid-turn/commit-only condensations) recorded 0. - Bug 2: `entire attach` never set the count, so it always wrote 0. - Counting change: derive the count from SessionTurnCount (every prompt, exec-mode safe) over a per-checkpoint window, with a deferred reset so back-to-back checkpoints report the same count instead of 0. Floored at 1. Decouples the combined-attribution gate (previously keyed off the now-floored checkpoints_count) onto a new SaveStepCount metadata field. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 615839a. Configure here.
| // window. Until then, back-to-back checkpoints keep reporting the same count. | ||
| if (event.TurnCount > 0 || event.Type == agent.TurnEnd) && state.PromptWindowResetPending { | ||
| state.PromptWindowBase = prevTurnCount | ||
| state.PromptWindowResetPending = false |
There was a problem hiding this comment.
Stale TurnEnd clears window reset
Medium Severity
After a checkpoint, PromptWindowResetPending is cleared whenever a lifecycle event has TurnEnd or TurnCount > 0, even if SessionTurnCount did not increase. A repeated Cursor Stop hook with the same cumulative loop count can re-anchor PromptWindowBase early, so a later back-to-back checkpoint shows 1 step instead of matching the prior count.
Reviewed by Cursor Bugbot for commit 615839a. Configure here.
There was a problem hiding this comment.
Pull request overview
This pull request fixes inaccurate (often zero) session “steps” in checkpoint metadata by redefining the displayed count to represent user prompts (derived from SessionTurnCount and a new prompt-window base), with a deferred window reset so back-to-back checkpoints without an intervening prompt keep the same step count. It also introduces SaveStepCount to preserve the previous “did SaveStep actually run?” signal for combined-attribution gating.
Changes:
- Compute displayed steps as
SessionTurnCount - PromptWindowBase(floored to 1) and defer window resets until the next counted turn. - Add
SaveStepCountto committed session metadata and switch combined-attribution gating to use it instead ofcheckpoints_count == 0. - Ensure
entire attachwrites a non-zero displayed step count; add/adjust tests for the prompt-window behavior.
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/strategy/manual_commit_test.go | Updates test setup to reflect new CheckpointsCount semantics (prompt-window-based). |
| cmd/entire/cli/strategy/manual_commit_hooks.go | Changes combined-attribution gating from CheckpointsCount to new SaveStepCount. |
| cmd/entire/cli/strategy/manual_commit_condensation.go | Introduces checkpointStepCount, writes SaveStepCount, and sets deferred reset flag after condensation. |
| cmd/entire/cli/strategy/manual_commit_condensation_test.go | Adds unit test coverage for checkpointStepCount window math and flooring behavior. |
| cmd/entire/cli/session/state.go | Adds PromptWindowBase and PromptWindowResetPending to session state to support deferred window resets. |
| cmd/entire/cli/lifecycle.go | Implements deferred prompt-window re-anchoring when a turn is first counted after checkpoint write. |
| cmd/entire/cli/lifecycle_test.go | Adds tests for deferred reset behavior and exec-mode cumulative TurnCount handling. |
| cmd/entire/cli/checkpoint/committed.go | Persists new SaveStepCount field into committed session metadata. |
| cmd/entire/cli/checkpoint/checkpoint.go | Adds SaveStepCount to options/metadata types (but one existing comment now mismatches semantics). |
| cmd/entire/cli/attach.go | Ensures attached checkpoints write a non-zero displayed steps count via attachStepCount. |
cd76a73 to
6fd16aa
Compare
- Only re-anchor the prompt window when SessionTurnCount actually increases, so a repeated/stale hook (same cumulative TurnCount) no longer clears the deferred reset early and break back-to-back checkpoint counts (Cursor bug). Adds a regression test. - Correct the checkpointStepCount doc (attach uses attachStepCount, not this path) and the WriteCommittedOptions.CheckpointsCount comment (now a prompt "steps" count, not a checkpoint count). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
attachStepCount floored on len(prompts), but prompts is only ever [meta.FirstPrompt] (≤1), so every attached session reported 1 step regardless of length. Use meta.TurnCount (the user-prompt count already parsed from the transcript) instead, still floored at 1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
6fd16aa to
d54a4e8
Compare
Entire-Checkpoint: 29533fb28a76


Problem
The "steps" count shown for each session in the UI was often wrong — and frequently 0. It was sourced from the CLI's
StepCount, which only counted turns that modified files and reset to 0 after every condensation. Roughly 1 in 5 recent checkpoints displayed "0 steps".Three issues:
git commit(commit-only sessions) condense before any step is recorded, so the count was 0.entire attachignored it. The attach path never set the count at all, so every attached checkpoint wrote 0.E.g.
But session has clearly two prompts before the checkpoint https://entire.io/gh/entireio/cli/session/eaa96109-502f-4be2-9357-cf4fde90deef#timeline-46304ab84156
Solution
One concept everywhere: a checkpoint's "steps" = the number of user prompts in that checkpoint's window (prompts since the previous checkpoint, with a deferred reset). Derived from the existing
SessionTurnCount(counts every turn, and is safe for exec-mode agents that report turns via hooks):Scenarios
entire attachAttach is the same counting concept applied post-hoc. The hooks never fired, so instead of live turn events it counts the user prompts parsed from the transcript (
meta.TurnCount), floored at 1. Attach produces a single checkpoint covering the whole session, so its window = the whole transcript = the total prompt count. (Earlier this countedlen(prompts), which only ever held the first prompt — so every attached session reported 1 regardless of length.)Related
The combined-attribution gate previously keyed off
checkpoints_count == 0. Since that's now floored to ≥1, the gate moves to a new honestSaveStepCountmetadata field ("did a real SaveStep run?").Forward-only — existing rows keep their stored values (no backfill); the API/frontend pass the value through unchanged.
🤖 Generated with Claude Code