Skip to content

fix(telemetry): the last small defects from the R1 audit - #1055

Merged
blafourcade merged 7 commits into
nextfrom
fix/telemetry-small-defects
Oct 17, 2026
Merged

blafourcade merged 7 commits into
nextfrom
fix/telemetry-small-defects

Conversation

@blafourcade

@blafourcade blafourcade commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

🎯 What & why

The last small telemetry defects from the R1 audit. Each one was reproduced or measured first, and only the ones that reproduced were fixed. The rest became one limit line or nothing.

🛠️ How it works

# Candidate Evidence Decision
1 report --days <huge> --days 99999999999: RangeError: Invalid time value stack, exit 1. --days 99999999: period -271764-02 to …, exit 0. 0, -1 and 1e9 were already refused cleanly Fixed. The first day goes through the window's four-digit bound, and a value past it is refused: --days reaches before the year 0000: give fewer days., exit 1
2 report | head -1 EPIPE Error: write EPIPE stack, exit 1, three runs out of three Fixed in cli.ts. A closed stdout drops only what is left to print. The run then exits on its own outcome, and any other stdout error still throws. cli/.claude/skills/command does not exist, so this follows 3-cli-process.md instead (process channels belong to cli.ts)
3 forget "repositorys" Red unit test: expected [...] to include '2 repositories declared...' Fixed. plural takes an irregular form
4 reasoning / advisor cache_write_1h null Read-only, ~/.claude/projects, 2,795 files, 266,992 usage lines. usage.output_tokens_details.thinking_tokens is on 188,677 lines, always a count, and never above output_tokens. On multi-iteration lines it exceeds the largest iteration's output 452 times out of 2,570, so it covers the whole call. Advisor iterations carry cache_creation.ephemeral_1h_input_tokens 2,460 times out of 2,460, all zero, and 5m + 1h = write every time. No advisor iteration carries output_tokens_details Fixed. The main record keeps the thinking count as reasoning. An advisor record keeps its own one-hour write. An advisor's reasoning stays null, since that case was never observed
5 10-min ledger lock The lock already stores a PID and checks that it is alive. The 10-min age rule clears it whatever the PID says. Earlier figures: 4.5 s for 250k records, 20.8 s for 1M. This machine's whole history is about 267k usage lines Limit line in the usage contract, no code. Awaiting decision. The cheap fix is to stop clearing a lock whose PID is alive. That fixes a holder still alive after sleep or a long run. The cost: after a crash or reboot, a reused PID keeps the lock looking alive, and every waiter fails after waitMs (60 s) with the existing error naming the lock file to remove. That failure is visible, not silent
6 Attribution O(calls × declarations) Synthetic report path (filter + buildReport --axis task, which call attribute twice per record), 250k calls: 300 ms with no declarations, 885 ms with 200 session declarations + 50 carries + 100 branches, 1,194 ms with 300/100/300 Nothing. That adds 0.59 to 0.89 s, under the 1 s bar but close to it. If you want it lower, the fix that deletes code is to attribute each record once and pass the result on
7 01-usage skill gaps Envelope keys and flags checked against report --json and --help. Every filter conflict the skill states was checked against the CLI Fixed two gaps. coverage.left_out spans every day, not only the period. Reasoning tokens are counted in output

Limit lines added to usage-contract.md: the lock age, and records stored before this change, which keep reasoning and the advisor one-hour write null.

🧪 How to verify

  • cd cli && pnpm test
  • aidd telemetry report --days 99999999999 → one error line, exit 1
  • aidd telemetry report | head -1 → no stderr, exit 0

Red runs, before each fix:

  • period: {"from":"-000001-12"} received where a refusal was expected
  • e2e: + Error: write EPIPE
  • display: expected [...] to include '2 repositories declared...'
  • parser: [null, null] vs [120, null], and null vs 3

⚠️ Heads-up

  • Candidate 5 is waiting on a decision (above).
  • Mutation on the changed logic lines: Stryker killed 19 of 20. The one survivor is > to >= at MAX_SHIFT in period.ts. It is equivalent: at exactly 3,652,425 days, both branches return null from any four-digit today. The cli.ts listener is covered by the e2e test only, because Stryker never reaches the built binary, so it was mutated by hand: flipping !== to === turns the e2e test red (+ Error: write EPIPE).
  • Net: +102 / -8 across 11 files.

🔗 Linked issue

None. Found by the R1 telemetry audit.

✅ I certify

  • I DO CERTIFY I READ EACH LINE OF THE PULL REQUEST BECAUSE I AM A SOFTWARE ENGINEER, NOT A AI PUPPY.

🤖 Generated with Claude Code

https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp

blafourcade and others added 7 commits October 17, 2026 20:57
`--days 99999999999` crashed with a RangeError stack, and `--days 99999999`
printed a period from "-271764-02". The first day now goes through the same
four-digit bound as the window, and past it the command says so and exits 1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
`aidd telemetry report | head -1` printed an unhandled EPIPE stack and
exited 1. A closed stdout now only drops what is left to print: the run
exits on its own outcome, and any other stdout error still throws.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
… says

Claude Code transcripts carry `usage.output_tokens_details.thinking_tokens`
(about 189k of 267k usage lines on one machine, never above output) and
an advisor iteration's own `cache_creation.ephemeral_1h_input_tokens`
(2,460 of 2,460). The reader stored both as null. `reasoning` now takes
the thinking count for the call, and an advisor record its one-hour
write; an advisor's reasoning stays null, as no advisor line says it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
The ledger lock is cleared after 10 minutes even while its holder runs;
no measured ingest comes near it. Records stored before the reader kept
reasoning and the advisor one-hour write stay null.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
`coverage.left_out` counts calls and lines from any day, so a report of
a period must not present them as its own. A question about reasoning
or thinking tokens now gets the answer that they are in `output`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
… calls carry one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWNxk63AGKkqE8HRqHLjGp
@blafourcade
blafourcade marked this pull request as ready for review October 17, 2026 19:45
@blafourcade
blafourcade requested a review from a team as a code owner October 17, 2026 19:45
@blafourcade
blafourcade merged commit 5a46c34 into next Oct 17, 2026
32 checks passed
@blafourcade
blafourcade deleted the fix/telemetry-small-defects branch October 17, 2026 19:45
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