claudemd-cli 0.21.5 → 0.21.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,70 @@ All notable changes to the `claudemd` plugin. This changelog tracks plugin artif
|
|
|
8
8
|
- **Canonical spec version source**: `spec/CLAUDE.md` top-line title (`# AI-CODING-SPEC vX.Y.Z — Core`) + `spec/CLAUDE-changelog.md` top `##` entry.
|
|
9
9
|
- **Plugin semver vs spec semver** are independent: plugin patch (0.2.0 → 0.2.1) may ship when spec is unchanged (this release); plugin minor (0.1.9 → 0.2.0) ships when spec minor updates (v0.2.0 shipped spec v6.10.0).
|
|
10
10
|
|
|
11
|
+
## [0.21.7] - 2026-05-24
|
|
12
|
+
|
|
13
|
+
**Patch — fix: audit `uniqueInvocations.duplicate_rows` was misleading without the "non-null tool_use_id" guard. Now split into `_real` / `_legacy`. Spec unchanged at v6.13.2.**
|
|
14
|
+
|
|
15
|
+
### Why this patch
|
|
16
|
+
|
|
17
|
+
The v0.21.5 audit incorrectly flagged "PreToolUse double-fire bug" against `banned-vocab` (90 dupes) and `pre-bash-safety` (59 dupes). Phase-1 reproduction against `~/.claude/logs/claudemd.jsonl` found:
|
|
18
|
+
|
|
19
|
+
- banned-vocab: 6 real-session rows with non-null `tool_use_id`, **0 collisions**
|
|
20
|
+
- pre-bash-safety: 48 real-session rows with non-null `tool_use_id`, **0 collisions**
|
|
21
|
+
- All-hook global check: 0 true double-fires
|
|
22
|
+
|
|
23
|
+
The 90 / 59 reported "dupes" were all from pre-v0.9.34 legacy rows (null `tool_use_id`) where two distinct hook invocations within the same wall-clock second collided on the `(ts, hook, session, tool_use_id)` quadruple — an artifact of seconds-precision `date -u +%Y-%m-%dT%H:%M:%SZ` timestamps in `rule_hits_append`, NOT a registration / lib bug.
|
|
24
|
+
|
|
25
|
+
The audit docs (`rule-hits-parse.js:114-117` and `commands/claudemd-audit.md` field table) DID name the "non-null tool_use_id" guard, but the headline metric (`duplicate_rows`) was a bare sum across both legacy noise and real signal. Easy to misread under reading-fatigue.
|
|
26
|
+
|
|
27
|
+
### What changed
|
|
28
|
+
|
|
29
|
+
- `scripts/lib/rule-hits-parse.js#uniqueInvocations`: per-hook output gains `duplicate_rows_real` (collision row has non-null `tool_use_id` → true double-fire bug signal) and `duplicate_rows_legacy` (collision row has null `tool_use_id` → expected noise from pre-v0.9.34 legacy rows OR Stop/SessionStart-class hooks). `duplicate_rows = _real + _legacy` retained for backward compat. Docstring rewritten with explicit reading guide.
|
|
30
|
+
- `commands/claudemd-audit.md`: field-table entry for `uniqueInvocations` rewritten with the split; the operator-format paragraph changed from "Surface `duplicate_rows > 0`..." to "Surface `duplicate_rows_real > 0`... **Do NOT report bare `duplicate_rows`**". The bare-sum is now explicitly called out as a misread trap.
|
|
31
|
+
- `tests/scripts/audit.test.js`: existing v0.9.34 test extended with `duplicate_rows_real=1, duplicate_rows_legacy=0` assertion. New v0.21.7 test covers three collision shapes (real bug / Stop-class noise / pre-v0.9.34 legacy noise) and asserts each routes to the correct counter.
|
|
32
|
+
- `feedback_audit_no_reverify.md`: trap-rule bullet added — "Read field-guards in full, not just headline metrics". Cites today's misread as the origin.
|
|
33
|
+
|
|
34
|
+
### Backward compatibility
|
|
35
|
+
|
|
36
|
+
- `duplicate_rows` field unchanged (sum). Consumers reading the bare sum keep working but will under-report or over-report depending on interpretation; new readers should switch to `_real` / `_legacy`.
|
|
37
|
+
- No change to any hook code; no spec change; no migration. Pure reporting-layer fix.
|
|
38
|
+
|
|
39
|
+
### Verification
|
|
40
|
+
|
|
41
|
+
- 448 unit + 2 integration tests pass (was 447 unit; +1 new test).
|
|
42
|
+
- Functional re-check against current `~/.claude/logs/claudemd.jsonl` (30d window): all hooks `duplicate_rows_real = 0`. The original audit's "bug" disappears once the gate is applied correctly.
|
|
43
|
+
|
|
44
|
+
## [0.21.6] - 2026-05-24
|
|
45
|
+
|
|
46
|
+
**Patch — feat: `runSpecSizingCheck` now emits copy-paste-ready OLD/NEW edits on drift. Spec unchanged at v6.13.2.**
|
|
47
|
+
|
|
48
|
+
### Why this patch
|
|
49
|
+
|
|
50
|
+
`feedback_spec_sizing_recursive_rewrite.md` hit its 4th in-session repro during the v0.21.5 ship: initial Sizing claim was −127B off from actual, requiring a second corrective edit to land inside the ±20B envelope. The drift detection itself worked (since v0.21.2) — what wasted iterations was the manual translation from "claim says 47700, actual is 47573" to "I need to edit the Sizing line to say 47573". Post-ship code review elevated this from candidate to next-patch actionable; this patch lands it.
|
|
51
|
+
|
|
52
|
+
### What changed
|
|
53
|
+
|
|
54
|
+
- `scripts/version-cascade-check.js#extractSizingClaim`: return shape changed from `number | null` to `{value, matched, suggestReplacement(actual)} | null`. The `matched` substring captures the exact span in the Sizing line (e.g. `extended 46071 → 47700 bytes`); `suggestReplacement(actual)` produces the corrected form (e.g. `extended 46071 → 47573 bytes`).
|
|
55
|
+
- `runSpecSizingCheck`: over-threshold drifts now include a `suggested: {old, new}` field with the OLD/NEW pair. Backward-compatible — the `claimed / actual / delta` fields are unchanged; consumers ignoring `suggested` keep working.
|
|
56
|
+
- CLI output: each over-threshold drift now prints a 3-line block — original drift line + indented `Suggested edit in **Sizing** line:` header + OLD/NEW pair. Bottom hint reworded from "Iterate until exit 0" to "apply the OLD→NEW pairs above (single corrective pass typically suffices)".
|
|
57
|
+
- `tests/scripts/version-cascade-check.test.js`: +2 synthetic tests — arrowed-form drift carries correct suggested edit; plain-form drift (no arrow) also carries correct suggested edit.
|
|
58
|
+
|
|
59
|
+
### Backward compatibility
|
|
60
|
+
|
|
61
|
+
- `extractSizingClaim` return-shape change is internal (not exported). Only `runSpecSizingCheck` is exported.
|
|
62
|
+
- `runSpecSizingCheck` return shape gains a `suggested` field on `over-threshold` drifts only. `claim-parse-failed` and `file-missing` drifts unchanged. Existing tests at all 3 boundary cases (no drift / ±20B inclusive / ±21B exclusive) keep passing without touching the assertions.
|
|
63
|
+
- CLI stderr format adds 3 lines per over-threshold drift. No change to exit codes or success-case stdout.
|
|
64
|
+
|
|
65
|
+
### Verification
|
|
66
|
+
|
|
67
|
+
- `npm test`: 447 unit + 2 integration suites pass (previously 445 unit; +2 new synthetic tests for arrowed-form and plain-form drift).
|
|
68
|
+
- Functional smoke: synthetic fixture with extended +50B drift (arrowed) and OPERATOR.md +100B drift (plain) → both `suggested.old` / `suggested.new` produce the expected corrected substrings.
|
|
69
|
+
|
|
70
|
+
### Followup status
|
|
71
|
+
|
|
72
|
+
- P6 (this patch) shipped. `tasks/improvement-candidates-2026-05.md` marks it done.
|
|
73
|
+
- P1 / P2 / P4 unchanged; P5 closed in v0.21.5.
|
|
74
|
+
|
|
11
75
|
## [0.21.5] - 2026-05-24
|
|
12
76
|
|
|
13
77
|
**Patch — clarify: memory-layer terminology cleanup. Spec bumped v6.13.1 → v6.13.2 (clarification only, identical Agent behavior).**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudemd-cli",
|
|
3
|
-
"version": "0.21.
|
|
3
|
+
"version": "0.21.7",
|
|
4
4
|
"description": "Standalone CLI for §10-V banned-vocab + transcript scanning. Companion to the claudemd Claude Code plugin (github.com/sdsrss/claudemd) for use in git pre-commit hooks, GitHub Actions, and other agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|