fix(analytics): escape the NUL separator so usage-ledger stops being binary - #30
Merged
Conversation
…binary The compound cache key in summarize() used a raw 0x00 byte written directly into the source — a literal control character, not the escape sequence. Git classifies a file with a NUL in its first 8000 bytes as binary, so `git diff` reported "Bin 9679 -> 10779 bytes" instead of the change, `git blame` stopped working, and `file` reported `data` rather than UTF-8 text. Worth noting how it got in: I merged it in #17, and the reason nobody caught it is the bug itself — the file was undiffable, so review had nothing to look at. The separator choice is fine: NUL cannot collide with a YYYY-MM month or any agent_id. Only the encoding was wrong. Both occurrences are now the escape sequence, which evaluates to the same U+0000 character, so getWorkspaceUsage / getPlatformUsage group byte-identically. Verified: 0 NUL bytes remain, `file` reports UTF-8 text, the template still evaluates to a string containing U+0000, and an end-to-end aggregation still separates same-month agents correctly. npm test 678/678. Found by the background session on PR #27, which was branched before #23 and would have reverted that PR's documentation on this file; applied directly to main instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Aug 9, 2026
oratis
added a commit
that referenced
this pull request
Aug 9, 2026
…nded (#31) Two defects found while reviewing the #23–#30 batch, both now on main. **Wrong PR credited.** #29's .gitattributes header and memory.md §6 both say #27 fixed the usage-ledger NUL bytes. #27 was closed as a duplicate — #30 landed the identical fix (verified byte-for-byte identical trees). Anyone following the reference lands on a closed PR with an empty diff. **The count treadmill.** #26 corrected five hardcoded test counts from 234/377/656 to the then-accurate 678. #28 merged minutes later and made it 679, so a PR whose entire purpose was de-staling docs shipped a number that was stale on arrival. Five copies of a figure that changes on every test-bearing merge cannot stay right. Counts are now stated as a magnitude pinned to a commit ("~680 as of c7c7d5b") with an instruction to measure instead of cite, and the two places that only needed "all green" no longer carry a number at all. The prose that never had one ("Vitest files under client/src/{...}") aged fine through this whole batch, which is the argument. memory.md §5.2 records the pattern so the next doc pass doesn't reinstate it. The remaining 234/656 mentions are deliberate — they are the history being explained, not live facts. Verified: 679/679 serialized on this branch; grep confirms no stale hardcoded count or bare #27 reference survives. Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
summarize()'s compound cache key used a raw0x00byte written directly into the source — a literal control character, not the escape sequence. Git classifies a file with a NUL in its first 8000 bytes as binary, so:git diffBin 9679 -> 10779 bytes(the real change is invisible)git blamefiledata, not UTF-8 textWorth noting how it got in: I merged it in #17, and the reason nobody caught it is the bug itself — the file was undiffable, so review had nothing to look at.
The separator choice is fine: NUL can't collide with a
YYYY-MMmonth or anyagent_id. Only the encoding was wrong. Both occurrences are now the escape sequence, which evaluates to the same U+0000 character, sogetWorkspaceUsage/getPlatformUsagegroup byte-identically.Test plan
filereportsUnicode text, UTF-8 text"2026-08" + NUL + "research")2026-08/research=8, 2026-08/strategy=7, total 15)npm test678/678Credit
Found by the background session on #27. That branch was cut before #23 and would have reverted that PR's documentation on this same file, so the two-byte fix is applied to current main instead and #27 can close.
🤖 Generated with Claude Code