Skip to content

v2.125.15: work-review never shows an unmeasured figure as 0; flag skills installed twice; plugin changes need a version bump - #20

Merged
gitayg merged 6 commits into
mainfrom
claude/festive-lamport-3ifp10
Oct 30, 2026
Merged

gitayg merged 6 commits into
mainfrom
claude/festive-lamport-3ifp10

Conversation

@gitayg

@gitayg gitayg commented Oct 29, 2026 •

Copy link
Copy Markdown
Owner

Three fixes for work-review, ideas taken from the Productizer plugin.

1. An unmeasured figure is never shown as 0

The bug: upload.mjs turned every missing figure into 0. So a week with no commits reached the hub as $0.00 per commit, and later it looked like a perfect week. Usage from a model with no known price also added $0, and nothing on the hub said the total was incomplete.

The fix:

  • Uploader: sends null for anything not measured. It also sends totals.unpricedTokens, the tokens from models it has no price for.
  • Hub validate(): keeps null; it still rejects anything that isn't a number.
  • Team view: a median with no data is null, not 0.
  • Page: shows a dash for anything not measured, including the setup counts. When some tokens have no price, the cost reads "incomplete". The trend chart leaves out snapshots with no cost instead of plotting them at $0.
  • Digest email: says "not measured" in the body and leaves the cost out of the subject, never "$0.00".

2. skill-installed-twice in the setup audit

The problem: a personal or project copy of a skill doesn't replace the same skill from a plugin, because plugin skills are namespaced. Both load and compete for the same requests, and claude plugin update updates only the plugin's copy, so the two drift apart.

The fix: audit-setup.mjs now also reads installed plugin skills. It lists them without judging them, and flags any skill installed at two scopes, once per skill name. A symlink to the same file counts as one install. Skills nobody here can edit, such as two cached versions of one plugin, are not reported as overlapping. The finding has a line in references/best-practices.md, marked as our own rule because the Claude Code docs don't cover this case.

3. A plugin change needs a version bump

The problem: plugin.json sets an explicit version, and Claude Code installs an update only when that version changes. A change to the plugin that keeps the version never reaches people who already installed it.

The fix:

  • plugins/releases.json: records each marketplace plugin's version and a hash of its files.
  • test/plugin-releases.test.js: fails when a plugin's files change but its version doesn't.
  • npm run gen:plugin-releases: refuses to record such a change, so regenerating can't cover it up.
  • CLAUDE.md: a short section describing the step.

The guard caught both of this PR's commits, so work-review is now 1.1.1.

Testing

  • New and updated tests: work-review-* and plugin-releases, 34 tests, all pass. The tests added for the Bugbot findings fail on the code before the fix.
  • Hub page: rendered in Chromium with every figure unmeasured, with no page errors and no literal "null" or "$0" shown.
  • Full npm test: 3,865 tests; 3,763 pass and 31 fail. The 31 are the same git and Docker tests that fail on a clean main in this environment, none in files this PR touches. CI's full run passes.
  • Other checks: the CI watchdog scripts and both claude plugin validate --strict runs pass.

🤖 Generated with Claude Code

https://claude.ai/code/session_01X2X5cmFm94J9Gz2esCZBEG


Note

Low Risk
Changes are scoped to the Work Review plugin, example hub, and plugin release tooling; no auth or core hosting paths, with dedicated tests for null semantics and duplicate-skill detection.

Overview
v2.125.15 tightens Work Review so missing analytics are not mistaken for zeros, adds a setup-audit finding for duplicate skills, and introduces release discipline for marketplace plugins.

Unmeasured figures → null, UI shows "—" / "incomplete"
The uploader, hub validate(), team medians, weekly digest, and hub page now preserve null for anything not measured (instead of coercing to 0). The hub accepts totals.unpricedTokens and surfaces incomplete cost when some model usage has no price. Charts skip snapshots without cost rather than plotting $0.

New skill-installed-twice setup finding
audit-setup.mjs inventories plugin-cached skills and flags the same skill name installed in two scopes (project/user vs plugin), with symlink deduping and overlap suppression; digest and best-practices docs include the fix text.

Plugin changes must bump plugin.json version
Adds plugins/releases.json, npm run gen:plugin-releases (refuses file changes without a version bump), test/plugin-releases.test.js, and CLAUDE.md guidance. work-review ships as 1.1.4 with recorded hash.

Reviewed by Cursor Bugbot for commit b5ddad6. Bugbot is set up for automated code reviews on this repo. Configure here.

…udit flags a skill installed twice; plugin changes need a version bump

- The uploader sends a figure the analyzer could not measure as null, not 0, and the hub stores and shows it as a dash. A week with no commits no longer reads as $0.00 per commit. Team medians over nobody are null, not 0.
- The upload now carries the tokens from models with no known price, and the hub marks the cost as incomplete rather than understating it.
- audit-setup reads installed plugin skills and adds skill-installed-twice: the same skill at two scopes, for example a personal copy beside a plugin's. Both load and compete, and a plugin update moves only one copy. A symlink to the same file counts as one install.
- plugins/releases.json records each marketplace plugin's version and file hash. test/plugin-releases.test.js fails when a plugin's files change without a version bump, and npm run gen:plugin-releases refuses to record such a change. work-review is now 1.1.0, so existing installs receive these changes.

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

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread examples/work-review-hub/index.html
Comment thread examples/work-review-hub/digest.mjs
Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs Outdated
…measured as null or $0.00; cached plugin copies are not an overlap

- Hub page: unmeasured setup counts show as dashes, not the word "null".
- Digest: an unmeasured week's cost is "not measured" in the body and left out of the subject, never $0.00; a finding with no share omits the percentage.
- audit-setup: skills nobody here can edit (synced, or two cached versions of one plugin) are not reported as overlapping; skill-installed-twice fires once per skill name.
- work-review plugin 1.1.1 (the version guard caught this change).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X2X5cmFm94J9Gz2esCZBEG
…lease renumbered to 2.125.15

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X2X5cmFm94J9Gz2esCZBEG
@gitayg gitayg changed the title v2.125.14: work-review never shows an unmeasured figure as 0; flag skills installed twice; plugin changes need a version bump v2.125.15: work-review never shows an unmeasured figure as 0; flag skills installed twice; plugin changes need a version bump Oct 30, 2026

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs
Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs Outdated
…aming every copy, plugin warning kept; managed-only pairs skipped

- A skill at project, user and plugin scope was reported as a local pair only, losing the plugin update-drift warning; copies are now grouped by name and the finding names each scope.
- A synced copy beside a plugin's (neither editable here) is no longer flagged.
- work-review plugin 1.1.2.

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

gitayg commented Oct 30, 2026

Copy link
Copy Markdown
Owner Author

role-and-shadow-check failed on 2b5dc97 in one live Docker test. The failure is not this PR's.

  • What failed: 1 of 3,962 tests: test/volume-seed.test.js:456, "the throwaway container is gone and its anonymous volume with it". This PR changes no Docker or volume code.
  • What the test checks: it records the dangling volumes before and after copyFromImage. Any volume that appears in between counts as a leak.
  • What it caught instead: the volume it reported, appcrane-vols-vrace-…-production, is the named volume of test/volume-race.test.js, which runs in parallel. That test removed its container inside the window, so its volume turned dangling at the same moment. An anonymous volume, which is what the test is meant to catch, always has a 64-character hex name.
  • CI re-run: CI is already running again on the new head, 09744ae.

Proposed patch (not added to this PR):

const leakedVolumes = [...await dangling()].filter((v) => !danglingBefore.has(v) && /^[0-9a-f]{64}$/.test(v));

Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 09744ae. Configure here.

Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs
…o it

When a project skill was also linked from user scope, the copies collapsed onto the link, and the advice said to delete the user copy, which would remove only the link. The real location now wins. Only the skill's own folder or file counts as a link, so a symlinked parent such as /tmp on macOS doesn't. work-review plugin 1.1.3.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X2X5cmFm94J9Gz2esCZBEG
Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs Fixed
Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs Fixed
Comment thread plugins/work-review/skills/work-review/scripts/audit-setup.mjs Fixed
…, not a path join (Semgrep path-join alerts); work-review plugin 1.1.4

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X2X5cmFm94J9Gz2esCZBEG
@gitayg
gitayg merged commit 5820d52 into main Oct 30, 2026
6 checks passed
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.

3 participants