Skip to content

fix(autorun): reconcile CLI Auto Run summary with cumulative session stats - #1284

Open
pedramamini wants to merge 1 commit into
rcfrom
fix/cumulative-autorun-summary
Open

fix(autorun): reconcile CLI Auto Run summary with cumulative session stats#1284
pedramamini wants to merge 1 commit into
rcfrom
fix/cumulative-autorun-summary

Conversation

@pedramamini

@pedramamini pedramamini commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fresh reimplementation of #735 on latest main. The original PR became unrebasable after the batch-processor rewrite (src/cli/services/batch-processor.ts +688/-573 and the useBatchProcessor.ts split +140/-1810). Closes #734.

Bug still reproduces (verified on current main)

The renderer path already gained history reconciliation during the rewrite (src/renderer/hooks/batch/internal/batchFinalSummary.ts via aggregateAutoRunHistoryTotals + mergeFinalSummaryTotals), so the desktop half of #735 is already covered by a more robust implementation.

The CLI path did NOT. On current main, createAutoRunSummary in src/cli/services/batch-processor.ts and the complete JSONL event were built purely from in-memory counters (totalCompletedTasks, totalInputTokens, totalOutputTokens, totalCost, Date.now() - batchStartTime). Those reset when a run spans an app/CLI restart, a resume, or a mid-run kill, so the final summary and the complete event undercount cumulative work. That is the remaining live half of the bug.

Fix

Reconcile the in-memory counters with persisted on-disk history before writing the summary and emitting the complete event:

  • Read history for the session, reconstruct cumulative totals from task entries written after the most recent final Auto Run ... summary (so it spans restarts but does not absorb earlier completed runs on the same session), and take Math.max of (in-memory, history-derived).
  • History-read failure is an expected/recoverable mode: fall back to the in-memory counters and logger.warn (does not bubble to Sentry).

To avoid duplicating the renderer's battle-tested logic (per CLAUDE.md dedup rules), the pure aggregate/merge helpers were extracted from batchFinalSummary.ts into a new shared module src/shared/autoRunHistoryReconciliation.ts. Both the renderer and the CLI now import it; batchFinalSummary.ts re-exports it so existing renderer importers and tests are unchanged. CLI per-task history entries now also stamp completedTaskCount so the shared aggregation counts checkboxes exactly (matching desktop Auto Run), rather than approximating one task per run entry.

Design deviations from #735

Files changed

  • src/shared/autoRunHistoryReconciliation.ts (new) - shared pure reconciliation helpers
  • src/renderer/hooks/batch/internal/batchFinalSummary.ts - moved helpers to shared, re-export
  • src/cli/services/batch-processor.ts - reconcile before summary/complete; stamp completedTaskCount
  • src/__tests__/cli/services/batch-processor.test.ts - restart-reconciliation, no-double-count, no-undercount, read-failure-fallback

Validation

  • tsc clean on all four configs: tsconfig.main.json, tsconfig.json, tsconfig.cli.json, tsconfig.lint.json
  • eslint clean on changed files
  • Full pre-push suite green: 34,054 passed / 108 skipped

Ready for review. Do not merge.

Summary by CodeRabbit

  • Bug Fixes
    • Auto Run summaries now retain accurate task counts, elapsed time, token usage, and costs after restarts.
    • Prevented previously completed runs from being counted again.
    • Improved handling when saved run history is delayed, empty, or temporarily unavailable.
    • Added a warning and safe fallback when run history cannot be read.

…stats

The CLI batch processor's Auto Run summary counters (tasks, tokens, cost,
duration) live only in memory, so they reset when a run spans an app/CLI
restart, resume, or mid-run kill. The final summary and JSONL complete event
then undercount cumulative work.

Reconcile the in-memory counters against persisted on-disk history before
building the summary: reconstruct totals from task entries written after the
last final 'Auto Run ...' summary and take Math.max with the live counters, so
stats survive restarts without absorbing earlier completed runs on the same
session. History-read failure is expected/recoverable: fall back to in-memory
counters and warn.

The renderer path already gained this behavior (batchFinalSummary.ts) after
the batch-processor rewrite that stranded #735. Extract the pure aggregate/
merge logic into src/shared/autoRunHistoryReconciliation.ts so the CLI reuses
the exact same battle-tested logic instead of duplicating it; batchFinalSummary
re-exports it for existing renderer importers. Also stamp completedTaskCount on
CLI per-task history entries so reconciliation counts checkboxes exactly.

Reimplements #735 on current main. Closes #734.
Copilot AI review requested due to automatic review settings July 22, 2026 20:02
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Auto Run reconciliation

Layer / File(s) Summary
Shared history aggregation and compatibility exports
src/shared/autoRunHistoryReconciliation.ts, src/renderer/hooks/batch/internal/batchFinalSummary.ts
Centralizes Auto Run history types, control-row filtering, cumulative aggregation, and runtime/history merging while preserving renderer exports.
CLI completion reconciliation
src/cli/services/batch-processor.ts
Reads persisted history, records per-task completion counts, and emits reconciled totals in summaries and completion events.
Restart and fallback validation
src/__tests__/cli/services/batch-processor.test.ts
Tests restart accumulation, completed-run boundaries, lagging history, and history-read failure fallback with logging.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant runPlaybook
  participant readHistory
  participant autoRunHistoryReconciliation
  participant JSONL
  runPlaybook->>readHistory: Read persisted AUTO history
  readHistory-->>runPlaybook: Return history entries
  runPlaybook->>autoRunHistoryReconciliation: Aggregate and merge totals
  autoRunHistoryReconciliation-->>runPlaybook: Return reconciled totals
  runPlaybook->>JSONL: Emit reconciled complete event
Loading

Possibly related PRs

Suggested reviewers: copilot, reachrazamair, chr1syy

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The changes aggregate summary totals across session history and cover tasks, duration, tokens, and cost as required by #734.
Out of Scope Changes check ✅ Passed The renderer refactor and new tests support the same reconciliation feature and do not introduce unrelated behavior.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly captures the main change: reconciling CLI Auto Run summaries with cumulative session statistics.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cumulative-autorun-summary

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds cumulative history reconciliation to CLI Auto Run. The main changes are:

  • Moves reconciliation helpers into a shared module.
  • Reuses the shared helpers from the renderer and CLI.
  • Adds exact task counts to new CLI history rows.
  • Emits reconciled totals on normal CLI completion.
  • Adds tests for restart, boundary, lag, and read-failure cases.

Confidence Score: 4/5

The cumulative CLI totals can still be wrong on halted, non-looping, and legacy-history paths.

  • Halted resumed runs return before reconciliation.
  • Non-loop runs leave no boundary for the next run.
  • Legacy multi-task rows are counted as one task each.
  • The shared import and renderer re-export surfaces appear compatible.

src/cli/services/batch-processor.ts and src/shared/autoRunHistoryReconciliation.ts

Important Files Changed

Filename Overview
src/cli/services/batch-processor.ts Adds reconciliation for normal completion, but halted runs bypass it and non-loop runs omit the required history boundary.
src/shared/autoRunHistoryReconciliation.ts Centralizes cumulative aggregation, with boundary and legacy-row assumptions that can produce incorrect totals.
src/renderer/hooks/batch/internal/batchFinalSummary.ts Moves the existing pure helpers to shared code while preserving renderer imports through re-exports.
src/tests/cli/services/batch-processor.test.ts Covers normal restart reconciliation but not resumed halts, consecutive non-loop runs, or legacy multi-task rows.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[CLI Auto Run] --> B[Persist task history]
    B --> C{Completion path}
    C -->|Normal| D[Read session history]
    D --> E[Aggregate after final boundary]
    E --> F[Merge with runtime totals]
    F --> G[Write summary and complete event]
    C -->|Halt marker| H[Return with runtime totals]
    H --> I[Persisted totals omitted]
    G --> J{Final boundary written?}
    J -->|Non-loop run| K[No boundary]
    K --> L[Next run absorbs prior task rows]
Loading

Reviews (1): Last reviewed commit: "fix(autorun): reconcile CLI Auto Run sum..." | Re-trigger Greptile

Comment on lines +898 to +901
const reconciled = reconcileTotals();

// Add total Auto Run summary (only if looping was used)
createAutoRunSummary();
createAutoRunSummary(reconciled);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Halt Path Skips Reconciliation

When a halt marker is detected during a resumed run, the earlier halt branch emits process-local totals and returns before reaching this reconciliation. The complete event then omits work persisted before the restart, and no final Auto Run boundary is written, so a later run can absorb the halted run's task rows.

Context Used: CLAUDE.md (source)

break;
}
}
const currentRunEntries = orderedEntries.slice(previousFinalSummaryIndex + 1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Non-Loop Runs Lack Boundaries

A successful CLI run with looping disabled persists task rows but createAutoRunSummary skips its final summary when loopIteration === 0. On the next run for that session, this slice includes the already completed run, so the reconciled summary and JSONL event overcount its tasks, tokens, cost, and duration.

Context Used: CLAUDE.md (source)

return taskEntries.reduce<AutoRunHistoryTotals>(
(totals, entry) => {
const usageStats = entry.usageStats;
totals.totalCompletedTasks += Math.max(0, entry.completedTaskCount ?? 1);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Legacy Multi-Task Rows Undercount

CLI history created before this change has no completedTaskCount, so every legacy agent turn contributes exactly one task here. If a turn checked multiple boxes, a resumed run undercounts the completed tasks even though the row's token, cost, and elapsed totals are fully included.

Context Used: CLAUDE.md (source)

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a long-running CLI Auto Run accounting bug where the final summary and complete JSONL event could undercount cumulative work when an Auto Run spans restarts or resumes. It does this by reconciling the CLI's in-memory counters against persisted on-disk history using a shared, pure reconciliation module that is also reused by the renderer path.

Changes:

  • Added shared Auto Run history aggregation and merge helpers to reconcile runtime totals with persisted history totals.
  • Updated the renderer batch final summary module to import the shared helpers and re-export them to avoid changing existing renderer import sites.
  • Updated the CLI batch processor to (1) stamp completedTaskCount per task entry and (2) reconcile totals before writing the final summary and emitting the complete event, with a warn-and-fallback path on history read failure.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
src/shared/autoRunHistoryReconciliation.ts New shared pure helpers to aggregate Auto Run totals from persisted history and merge with runtime counters.
src/renderer/hooks/batch/internal/batchFinalSummary.ts Switched renderer to use the shared reconciliation helpers, while re-exporting to preserve existing imports.
src/cli/services/batch-processor.ts Reconciles CLI summary and complete event totals against persisted history; stamps completedTaskCount for accurate cross-restart task counting.
src/tests/cli/services/batch-processor.test.ts Adds CLI tests covering restart reconciliation, no double count across completed runs, no undercount when history lags, and fallback when history read throws.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto Run summary only reports last loop iteration, not cumulative session stats

2 participants