Skip to content

docs: add audit-grade snapshot workflow for billing reconciliation - #52

Merged
cobra91 merged 3 commits into
mainfrom
docs/audit-snapshot-workflow
Jul 20, 2026
Merged

docs: add audit-grade snapshot workflow for billing reconciliation#52
cobra91 merged 3 commits into
mainfrom
docs/audit-snapshot-workflow

Conversation

@cobra91

@cobra91 cobra91 commented Jul 20, 2026

Copy link
Copy Markdown
Owner

Responds to the field-data point raised in #40 by @lizhuojunx86.

Context

Claude Code rewrites session JSONL files on resume/compact and can drop earlier messages, which makes post-rewrite totals drift from actual usage (upstream bug anthropics/claude-code#36583). better-ccusage reads the files faithfully and intentionally does not reconstruct a different history (no shadow ledger).

@lizhuojunx86 pointed out that the snapshot workflow is "worth a line in the README for anyone doing billing reconciliation" — this adds it.

Change

New section "Audit-grade reports (snapshot before resume/compact)" in docs/guide/directory-detection.md (the natural home: it already documents Claude's data paths and the CLAUDE_CONFIG_DIR override). Includes:

No code changes. Docs lint clean.

Summary by CodeRabbit

  • Documentation
    • Added a new guide subsection, “Audit-grade reports (snapshot before resume/compact)”, explaining that session JSONL files may be rewritten/compacted during resume/compact, which can shift totals.
    • Provided step-by-step instructions to snapshot the Claude data directory (legacy and default roots), set CLAUDE_CONFIG_DIR to the frozen copy, and run reports (e.g., monthly breakdown) for accurate “as-of” totals.
    • Documented how to handle missing roots and noted the snapshot consists of plain JSONL files.

Claude Code rewrites session JSONLs on resume/compact, which can drop
earlier messages and make post-rewrite totals drift from actual usage
(upstream bug, anthropics/claude-code#36583). better-ccusage reads the
files faithfully and intentionally doesn't reconstruct a different
history. Document the recommended workaround: snapshot the Claude data
directory before resume/compact and point CLAUDE_CONFIG_DIR at the
snapshot for audit-grade reports.

Responds to the field-data point raised in #40 by @lizhuojunx86.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: db943c53-47b4-43e1-b46f-613f546f24e8

📥 Commits

Reviewing files that changed from the base of the PR and between 856bd8f and dc9212e.

📒 Files selected for processing (1)
  • docs/guide/directory-detection.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/guide/directory-detection.md

📝 Walkthrough

Walkthrough

The directory detection guide now documents how resume and compact can rewrite session history and provides a snapshot workflow for generating audit-grade usage reports.

Changes

Audit-grade reporting

Layer / File(s) Summary
Snapshot-based audit reporting
docs/guide/directory-detection.md
Documents session history rewriting during resume or compact, and explains how to snapshot Claude data, set CLAUDE_CONFIG_DIR, and run reports against the snapshot.

Estimated code review effort: 1 (Trivial) | ~3 minutes

Poem

I’m a rabbit with a frozen file,
Snapping logs in audit style.
Compact may rewrite what came before,
But snapshots keep the totals sure.
Hop, report, and check the score!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and accurately summarizes the new documentation about snapshotting Claude data for audit-grade billing reconciliation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/audit-snapshot-workflow

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.

@chatllm-code-bot

chatllm-code-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

⚠️ Code review agent could not produce a complete summary (did not submit a review within the step budget). Manual review recommended.

📁 Files Reviewed (1)
  • docs/guide/directory-detection.md
🕓 Previous Review Summaries (2 snapshots · latest 2af0c5f)
Snapshot — 2af0c5f

⚠️ Code review agent could not produce a complete summary (did not submit a review within the step budget). Manual review recommended.

📁 Files Reviewed (1)
  • docs/guide/directory-detection.md
Snapshot — 856bd8f

⚠️ Code review agent could not produce a complete summary (did not submit a review within the step budget). Manual review recommended.

📁 Files Reviewed (1)
  • docs/guide/directory-detection.md

Review automated by ChatLLM Code Bot using remote/Qwen3.6-35B-A3B with 8187 tokens (7627 in / 560 out)

@pkg-pr-new

pkg-pr-new Bot commented Jul 20, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/cobra91/better-ccusage@52
npm i https://pkg.pr.new/cobra91/better-ccusage/@better-ccusage/codex@52
npm i https://pkg.pr.new/cobra91/better-ccusage/@better-ccusage/mcp@52
npm i https://pkg.pr.new/cobra91/better-ccusage/@better-ccusage/opencode@52

commit: dc9212e

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/guide/directory-detection.md`:
- Around line 121-125: Update the snapshot workflow around CLAUDE_CONFIG_DIR to
include both supported Claude data roots, ~/.config/claude/projects and
~/.claude/projects. Copy each existing root into separate snapshot directories,
then set CLAUDE_CONFIG_DIR to their parent paths as a comma-separated value;
alternatively, explicitly state that the workflow only supports single-root
installations and revise the audit-grade totals claim.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 12faa738-2f61-4206-a263-ad4a474800a0

📥 Commits

Reviewing files that changed from the base of the PR and between 82dc274 and 856bd8f.

📒 Files selected for processing (1)
  • docs/guide/directory-detection.md

Comment thread docs/guide/directory-detection.md Outdated
@kilo-code-bot

kilo-code-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown

Code Review Roast 🔥

Verdict: No Issues Found | Recommendation: Merge

The previous review torched line 132 for claiming the CLAUDE_CONFIG_DIR list "naturally contains just that one path" while the export two lines up hardcodes both paths. This commit swaps that sentence for the actual mechanism — rmdir clears the empty stub, getClaudePaths() filters the stale entry, the report runs against the one real root. Verified against data-loader.ts:84-114: each comma-separated path must pass both isDirectorySync(path) and isDirectorySync(path/projects), so a ghost path is genuinely skipped, not magically absent.

I had the sarcasm loaded and the safety off, but the fix is... correct. Verbatim application of the prior suggestion, no new drift, prose now matches the runtime. I'm going to need a moment.

📊 Overall: Like watching someone actually read the review comments and fix the thing — rare enough that I double-checked the diff twice to make sure I wasn't being pranked.

Files Reviewed (1 file)
  • docs/guide/directory-detection.md - incremental reword of the single-root note (line 132); prior issue resolved, no new issues
Previous Review Summaries (2 snapshots, latest commit 2af0c5f)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 2af0c5f)

Verdict: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
🚨 critical 0
⚠️ warning 0
💡 suggestion 1
🤏 nitpick 0
Issue Details (click to expand)
File Line Roast
docs/guide/directory-detection.md 132 Prose claims the CLAUDE_CONFIG_DIR list "naturally contains just that one path" — but the hardcoded export always sets both $SNAP/config,$SNAP/legacy. The runtime survives via rmdir + getClaudePaths() filtering, but the env var literal contradicts the docs.

🏆 Best part: Genuinely impressed that the incremental change actually fixed the prior CodeRabbit finding (snapshot both roots instead of one) — and did it with 2>/dev/null || rmdir cleanup and quoted variables. That's the rare docs PR that responds to review by making the shell more robust, not less. Color me surprised.

💀 Worst part: The recipe markets itself as "audit-grade," then tells a reader the CLAUDE_CONFIG_DIR list "naturally contains just that one path" when it absolutely, literally does not. Audit-grade prose shouldn't require the reader to reverse-engineer getClaudePaths() to figure out what's true.

📊 Overall: Like a beautifully restored classic car with a misprinted speedometer — runs great, but the dashboard is lying to you about something you'd swear didn't matter until it does.

Files Reviewed (1 file)
  • docs/guide/directory-detection.md - 1 issue (prose contradicts the hardcoded export two lines above)

Fix these issues in Kilo Cloud

Previous review (commit 856bd8f)

Verdict: No Issues Found | Recommendation: Merge

Oh wait, this PR is actually clean. I need to sit down. I had my flamethrower warmed up and everything.

I came in ready to torch a docs PR — surely there'd be a broken command, a stale link, a CLAUDE_CONFIG_DIR pointing at the wrong subdirectory... something. Instead I found a snapshot recipe where $SNAP/projects lines up exactly with the CLAUDE_CONFIG_DIR/projects contract documented 80 lines above it, a monthly --breakdown invocation that's a verified-valid flag, and a genuinely useful upstream-bug reference. The bash even quotes its variables. Who hurt you into writing shell this carefully?

📊 Overall: Like finding a unicorn in production — I didn't think clean docs PRs existed anymore, but here we are.

Files Reviewed (1 file)
  • docs/guide/directory-detection.md — new "Audit-grade reports" section (lines 111-128); bash recipe verified against the directory-detection contract and the monthly --breakdown command surface

Reviewed by glm-5.2 · Input: 28.9K · Output: 5.3K · Cached: 242.3K

Address CodeRabbit major review: the audit snippet only snapshotted
~/.config/claude/projects, but better-ccusage aggregates BOTH that and
the legacy ~/.claude/projects/. Pointing CLAUDE_CONFIG_DIR at a single-
root snapshot would silently omit legacy-session usage, invalidating
the 'audit-grade totals' claim for users with data in both locations.

Copy each existing root into its own snapshot subdir and pass them all
as a comma-separated CLAUDE_CONFIG_DIR. Roots that don't exist are
skipped (cp || rmdir), so single-root installs naturally get a single-
path list.
Comment thread docs/guide/directory-detection.md Outdated
Address kilo-code review: the previous wording claimed the
CLAUDE_CONFIG_DIR list 'naturally contains just that one path' for
single-root installs, which is inaccurate — the env var still holds
both literal paths; it's better-ccusage that silently skips the
missing one at runtime. Reword to describe the actual mechanism
(rmdir removes the empty stub, the stale entry simply won't resolve)
so an auditor running 'echo $CLAUDE_CONFIG_DIR' isn't misled by a
ghost path.
@cobra91
cobra91 merged commit 4703e1e into main Jul 20, 2026
13 checks passed
@cobra91
cobra91 deleted the docs/audit-snapshot-workflow branch July 20, 2026 11:44
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.

1 participant