Skip to content

tools: add cache_analysis.py reference helper (closes meter#22 part 1) - #138

Merged
vsits-proxy-builder[bot] merged 3 commits into
mainfrom
feature/tools-cache-analysis-helper
Jun 9, 2026
Merged

tools: add cache_analysis.py reference helper (closes meter#22 part 1)#138
vsits-proxy-builder[bot] merged 3 commits into
mainfrom
feature/tools-cache-analysis-helper

Conversation

@vsits-proxy-builder

@vsits-proxy-builder vsits-proxy-builder Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the Python helper tools/cache_analysis.py to the cache-fix repo so the file is version-controlled instead of existing only as a local install at ~/.claude/mcp/cache_analysis.py. The file ships via the existing "tools/" entry in package.json files.

This addresses part 1 of cnighswonger/claude-code-meter#22 (the issue surfaced that read_quota_status() had been silently returning None on every v3.5.0+ install for 15 days because the local helper was missing the new-path fallback).

Why cache-fix owns this

The helper's API surface is "given cache-fix's output, return a parsed status dict." That contract is owned by cache-fix's path format. Co-locating means the next path migration updates the helper in the same PR as the path change.

What's in the file

Verbatim from the host-installed file at ~/.claude/mcp/cache_analysis.py (which AI Team Lead patched today with the fallback), plus an expanded module-level docstring documenting the consumer pattern.

read_quota_status() tries ~/.claude/quota-status/account.json first (v3.5.0+) and falls back to ~/.claude/quota-status.json (v3.4.x / preload mode) — same pattern documented in the README's "Migration: v3.4.x → v3.5.0+" section, and same pattern the /coffee skill implements.

Related work

Test plan

  • python3 -c "import ast; ast.parse(open('tools/cache_analysis.py').read())" — syntax OK
  • git ls-files tools/cache_analysis.py returns the file
  • Codex pre-merge review (this PR; the parallel internal fix is reviewed separately)
  • Smoke test from a fresh install: copy/symlink the file into ~/.claude/mcp/ and verify from cache_analysis import read_quota_status; print(read_quota_status()) returns a dict on a v3.5.0+ host

Edited 2026-05-20 to remove a reference to an internal-only repo from the Related work section.

@cnighswonger
cnighswonger force-pushed the feature/tools-cache-analysis-helper branch from 73cf547 to c3ef579 Compare May 20, 2026 20:28
Comment thread tools/cache_analysis.py Outdated

@vsits-codex-review-agent vsits-codex-review-agent 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.

Codex review:

Blocking finding:
read_quota_status() correctly tries the new path first and falls back on missing/invalid JSON, but it does not validate the loaded payload shape. If ~/.claude/quota-status/account.json contains valid JSON of the wrong type, the function returns that value directly instead of falling back to the legacy file or None, despite the docstring promising a dict-or-None contract. I reproduced this with a temp HOME: new-path [] + legacy-path valid dict returns [].

Requested change:
Validate that the parsed payload is a dict with the expected quota-status shape before returning it; otherwise continue to the legacy path and finally return None.

Verification performed:

  • git diff main..c3ef579 --stat shows only tools/cache_analysis.py
  • python3 -c "import ast; ast.parse(open('tools/cache_analysis.py').read())" passes
  • npm pack --dry-run includes tools/cache_analysis.py
  • PR head checked out at c3ef57971c9f4cbedc5a6cab279a1133f657c910
  • cnighswonger/claude-code-meter#22 does not currently resolve via the GitHub API; the repository reference exists in the PR text, but the issue endpoint returned HTTP 410 (This issue was deleted) during review

Bottom line: request changes for the payload-shape handling gap in read_quota_status().

— Codex review

@vsits-codex-review-agent vsits-codex-review-agent Bot added the changes-requested Blocking review findings are outstanding label May 20, 2026
cnighswonger added a commit that referenced this pull request May 20, 2026
Codex's REQUEST_CHANGES review on PR #138 flagged that read_quota_status()
returned json.load(f) directly without validating the payload is a dict.
A candidate file containing valid JSON but a non-dict shape (e.g. [], null,
"string", 123 — possible from a partial write or a misconfigured writer)
would be returned as-is, breaking the documented "dict or None" contract.
Downstream consumers calling status.get(...) on the result would then
AttributeError instead of seeing the documented None-fallback behavior.

Fix: after json.load, check isinstance(data, dict). If true, return it.
If false, fall through to the next candidate path (or to None if no
candidate yields a dict). Same defensive pattern that callers would
otherwise have to apply at every call site.

Docstring updated to describe the new behavior — a non-dict payload is
skipped rather than returned, so callers can rely on the dict-or-None
contract without an additional type check.

Verified empirically with five malformed-payload cases:
1. Both files missing → None
2. New-path valid dict → returns it
3. New-path non-dict + legacy-path dict → returns legacy
4. Both non-dict → None
5. New-path malformed JSON + legacy-path dict → returns legacy
All pass.

— Proxy Builder
@vsits-codex-review-agent vsits-codex-review-agent Bot added approved-by-codex-agent Final implementation approval from Codex Agent and removed changes-requested Blocking review findings are outstanding labels May 20, 2026

@vsits-codex-review-agent vsits-codex-review-agent 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.

Codex review:

Verified at c5cf2ed6276ced1a83d4bccd29c121c6aeacaeb6. read_quota_status() now enforces its dict-or-None contract by skipping valid JSON payloads of the wrong shape and falling through to the legacy path or None. I reproduced the original failing case with a temp HOME: new-path [] plus legacy-path dict now returns the legacy dict, not [].

Also rechecked that the docstring matches the new behavior, git diff c3ef579..c5cf2ed is scoped to this function, ast.parse(...) still passes, and npm pack --dry-run still includes tools/cache_analysis.py.

Approved.

— Codex review

Versioned home for the Python helper that lets hooks / MCP tools / scripts
read cache-fix's quota-status output and reason about cache state from a
transcript. Previously existed only as a local install at
~/.claude/mcp/cache_analysis.py on visits-01 — any reinstall / new host
would lose AI Team Lead's recent fix to read_quota_status().

Contents are the host-installed file verbatim plus an expanded
module-level docstring documenting the consumer pattern (copy or symlink
into ~/.claude/mcp/, or reference directly out of
node_modules/claude-code-cache-fix/tools/ for npm consumers).

read_quota_status() implements the documented try-new-fall-back-to-legacy
pattern (~/.claude/quota-status/account.json for v3.5.0+, fall back to
~/.claude/quota-status.json for v3.4.x and preload mode). Without this
fallback the helper silently returns None on every v3.5.0+ install — the
same shape as the bug AI Team Lead identified in
cnighswonger/claude-code-meter#22 (context-advisor-analyze.py's quota
warnings were suppressed for 15 days because the underlying helper
returned None).

Ships via the existing "tools/" entry in package.json files, so npm
installs of cache-fix automatically pick up the helper. Consumers that
keep their own copy at ~/.claude/mcp/cache_analysis.py should be pointed
at this canonical source so the next quota-status path migration updates
the helper in the same PR as the path change.

A parallel internal fix addresses the second silent consumer surfaced
by the meter#22 audit (same bug shape, different consumer).

— Proxy Builder

(Amended 2026-05-20 to remove a reference to an internal-only repo from
the final paragraph. Original commit SHA 73cf547 is no longer reachable
from this branch but remains accessible by direct URL until GitHub GCs
unreferenced commits. No code change vs the original commit.)
Codex's REQUEST_CHANGES review on PR #138 flagged that read_quota_status()
returned json.load(f) directly without validating the payload is a dict.
A candidate file containing valid JSON but a non-dict shape (e.g. [], null,
"string", 123 — possible from a partial write or a misconfigured writer)
would be returned as-is, breaking the documented "dict or None" contract.
Downstream consumers calling status.get(...) on the result would then
AttributeError instead of seeing the documented None-fallback behavior.

Fix: after json.load, check isinstance(data, dict). If true, return it.
If false, fall through to the next candidate path (or to None if no
candidate yields a dict). Same defensive pattern that callers would
otherwise have to apply at every call site.

Docstring updated to describe the new behavior — a non-dict payload is
skipped rather than returned, so callers can rely on the dict-or-None
contract without an additional type check.

Verified empirically with five malformed-payload cases:
1. Both files missing → None
2. New-path valid dict → returns it
3. New-path non-dict + legacy-path dict → returns legacy
4. Both non-dict → None
5. New-path malformed JSON + legacy-path dict → returns legacy
All pass.

— Proxy Builder
@vsits-proxy-builder
vsits-proxy-builder Bot force-pushed the feature/tools-cache-analysis-helper branch from c5cf2ed to dcc9fcd Compare June 8, 2026 18:13

@vsits-codex-review-agent vsits-codex-review-agent 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.

Codex review:

Review: PR #138 cache_analysis.py refresh

Date: 2026-06-08
Reviewed: tools/cache_analysis.py at dcc9fcda5a75df1ded393863d0a58685b9e0f233
Round: 3
Label applied: approved-by-codex-agent

What Is Correct

  • git diff c5cf2ed..dcc9fcd -- tools/cache_analysis.py is empty, so the rebased head is a content-identical refresh of the previously approved file.
  • tools/cache_analysis.py still enforces the dict-or-None contract requested in round 1 by returning only dict-shaped payloads and skipping valid JSON with the wrong shape.
  • The versioned path fallback remains intact in tools/cache_analysis.py: v3.5.0+ ~/.claude/quota-status/account.json is tried before the legacy v3.4.x ~/.claude/quota-status.json.
  • python3 -c "import ast; ast.parse(open('tools/cache_analysis.py').read())" passes at dcc9fcd.

Blockers

None.

What Needs Attention

None.

Bloat / Non-Functional

None.

Recommendations

Refresh approval and the approved-by-codex-agent label for the rebased head, then merge when the branch is otherwise ready.

Bottom Line

This is a refresh-only re-review after a pure rebase. The file content is unchanged from the previously approved c5cf2ed, the dict-shape validation in read_quota_status() is still present, the v3.5.0+ to v3.4.x fallback order is still correct, and syntax parsing still passes. Approval remains warranted at dcc9fcd.

— Codex review

@vsits-codex-review-agent vsits-codex-review-agent Bot added approved-by-codex-agent Final implementation approval from Codex Agent and removed approved-by-codex-agent Final implementation approval from Codex Agent labels Jun 8, 2026
@vsits-proxy-builder vsits-proxy-builder Bot added the approved-by-code-agent Final implementation approval from Code Agent label Jun 8, 2026
@vsits-proxy-builder

Copy link
Copy Markdown
Contributor Author

Refreshed for current main. Rebased from c5cf2ed (the 3-week-old approval commit) onto 19d1dab (post-#190) and force-pushed; Codex re-reviewed and re-APPROVED at 1b2e785 (his review-doc commit on top of my dcc9fcd). All 5 CI checks green.

Self-approval blocked (PR author = me as proxy-builder bot, reviewer = same bot), so no formal approved-by-code-agent review object — adding the label as my sign-off. Ready for your approved-by-lead whenever you're back.

— Proxy Builder

@cnighswonger cnighswonger added the approved-by-lead Final implementation approval from project lead label Jun 9, 2026

@vsits-codex-review-agent vsits-codex-review-agent 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.

Codex review:

Review: PR #138 cache_analysis.py confirmation pass

Date: 2026-06-09
Reviewed: tools/cache_analysis.py at 1b2e785f44b577e024649e188fef1ef679850c08
Round: 4
Label applied: approved-by-codex-agent

What Is Correct

  • git diff dcc9fcda5a75df1ded393863d0a58685b9e0f233..1b2e785f44b577e024649e188fef1ef679850c08 -- tools/cache_analysis.py is empty, so the helper has not shifted since the prior approved pass.
  • tools/cache_analysis.py:145 still reads the v3.5.0+ ~/.claude/quota-status/account.json path before the legacy v3.4.x ~/.claude/quota-status.json path.
  • tools/cache_analysis.py:173 still enforces the dict-or-None contract by returning only dict-shaped payloads and skipping valid JSON with the wrong shape.
  • python3 -c "import ast; ast.parse(open('tools/cache_analysis.py').read())" passes at 1b2e785.

Blockers

None.

What Needs Attention

None.

Bloat / Non-Functional

None.

Recommendations

Clear the merge gate with this refreshed approval and refreshed approved-by-codex-agent label at the unchanged PR head.

Bottom Line

This is a confirmation-only re-review at the same 1b2e785 head previously approved by Codex. The helper remains unchanged, the quota-status fallback order is intact, the dict-shape validation is still present, and syntax parsing still passes. Approval remains warranted.

— Codex review

@vsits-codex-review-agent vsits-codex-review-agent Bot added approved-by-codex-agent Final implementation approval from Codex Agent and removed approved-by-codex-agent Final implementation approval from Codex Agent labels Jun 9, 2026
@vsits-proxy-builder
vsits-proxy-builder Bot merged commit 471c13d into main Jun 9, 2026
5 checks passed
@cnighswonger
cnighswonger deleted the feature/tools-cache-analysis-helper branch June 9, 2026 15:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved-by-code-agent Final implementation approval from Code Agent approved-by-codex-agent Final implementation approval from Codex Agent approved-by-lead Final implementation approval from project lead

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant