feat(rules): warn-version-readme-changelog-sync + bump 1.15.0 (defense-in-depth ↔ dojo-os)#22
Conversation
Greptile SummaryThis PR adds a new Tier 2
Path to 5/5 Confidence1. Fix the bypass instruction for JSON manifest files — 2. Unify the bypass comment syntax — the 3. Add the missing Confidence Score: 3/5The manifest bumps and README/CHANGELOG changes are safe; the bypass instructions in the new rule's warning message would corrupt a JSON manifest if followed literally. The new rule's warning text directs users to embed a
|
| Filename | Overview |
|---|---|
| hooks/rules/rules.yaml | Adds warn-version-readme-changelog-sync Tier 2 rule with 11 tests; bypass instruction for JSON manifest files recommends embedding a comment syntax that is invalid in JSON, and message text (#) and test case (//) use different comment styles. |
| hooks/rules/rules.json | Generated file mirrors the new YAML rule correctly; same bypass-in-JSON issue inherited from the source YAML. |
| CHANGELOG.md | New file with reconstructed history; [1.15.0] reference link is missing from the footer and [Unreleased] still points to v1.14.0 instead of v1.15.0. |
| README.md | Adds Version: 1.15.0 line with links to CHANGELOG and Marketplace — clean, no issues. |
| package.json | Version bumped from 1.12.0 to 1.15.0 (spanning the stacked PR #21 delta); no issues. |
| .claude-plugin/plugin.json | Version bumped from 1.11.0 to 1.15.0; no issues. |
| .claude-plugin/marketplace.json | Both top-level and nested plugin version bumped from 1.12.0 to 1.15.0; no issues. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[Claude writes/edits manifest file] --> B{file_path matches\npackage.json /\nplugin.json /\nmarketplace.json?}
B -- No --> Z[Pass — no action]
B -- Yes --> C{content contains\n'version': 'X.Y.Z'?}
C -- No --> Z
C -- Yes --> D{bypass marker\npresent in any\ntool_input field?}
D -- Yes --> Z
D -- No --> E[WARN: version-readme-changelog-sync\nexit 0 message to stderr]
E --> F[Agent nudged to update\nREADME.md Version line\n+ CHANGELOG.md entry]
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 2
hooks/rules/rules.yaml:2222-2236
**Bypass instruction produces invalid JSON**
The warning message tells users to add `"# hook-bypass: version-readme-changelog-sync"` as a comment near the version field in `package.json`, `plugin.json`, or `marketplace.json`. JSON has no comment syntax — embedding either `#` or `//` style comments produces a file that fails JSON parsing, which would break `npm install`, CI pipelines, and any tool reading the manifest. The test case `allows-bypass-marker` reinforces the same invalid pattern (using `//` while the message text says `#` — a second inconsistency). The bypass message should drop the embedded-comment suggestion entirely for JSON targets and only describe the tool-call–level mechanism ("pass it on the Write call"), or document a safe alternative.
### Issue 2 of 2
CHANGELOG.md:228-229
The `[1.15.0]` reference link is missing from the footer, so the `## [1.15.0]` heading in rendered Markdown is not a clickable link. The `[Unreleased]` compare URL also still points to `v1.14.0` instead of the just-released `v1.15.0`.
```suggestion
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.15.0...HEAD
[1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
```
Reviews (1): Last reviewed commit: "docs(changelog): add 1.15.0 entry (dogfo..." | Re-trigger Greptile
| input: | ||
| tool_input: | ||
| file_path: 'CHANGELOG.md' | ||
| content: '## [1.15.0] - 2026-05-14' | ||
| expected_exit: 0 | ||
| - name: allows-bypass-marker | ||
| input: | ||
| tool_input: | ||
| file_path: 'package.json' | ||
| content: | | ||
| { | ||
| "version": "1.15.0" | ||
| // hook-bypass: version-readme-changelog-sync | ||
| } | ||
| expected_exit: 0 |
There was a problem hiding this comment.
Bypass instruction produces invalid JSON
The warning message tells users to add "# hook-bypass: version-readme-changelog-sync" as a comment near the version field in package.json, plugin.json, or marketplace.json. JSON has no comment syntax — embedding either # or // style comments produces a file that fails JSON parsing, which would break npm install, CI pipelines, and any tool reading the manifest. The test case allows-bypass-marker reinforces the same invalid pattern (using // while the message text says # — a second inconsistency). The bypass message should drop the embedded-comment suggestion entirely for JSON targets and only describe the tool-call–level mechanism ("pass it on the Write call"), or document a safe alternative.
Prompt To Fix With AI
This is a comment left during a code review.
Path: hooks/rules/rules.yaml
Line: 2222-2236
Comment:
**Bypass instruction produces invalid JSON**
The warning message tells users to add `"# hook-bypass: version-readme-changelog-sync"` as a comment near the version field in `package.json`, `plugin.json`, or `marketplace.json`. JSON has no comment syntax — embedding either `#` or `//` style comments produces a file that fails JSON parsing, which would break `npm install`, CI pipelines, and any tool reading the manifest. The test case `allows-bypass-marker` reinforces the same invalid pattern (using `//` while the message text says `#` — a second inconsistency). The bypass message should drop the embedded-comment suggestion entirely for JSON targets and only describe the tool-call–level mechanism ("pass it on the Write call"), or document a safe alternative.
How can I resolve this? If you propose a fix, please make it concise.| [Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.14.0...HEAD | ||
| [1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0 |
There was a problem hiding this comment.
The
[1.15.0] reference link is missing from the footer, so the ## [1.15.0] heading in rendered Markdown is not a clickable link. The [Unreleased] compare URL also still points to v1.14.0 instead of the just-released v1.15.0.
| [Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.14.0...HEAD | |
| [1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0 | |
| [Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.15.0...HEAD | |
| [1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0 | |
| [1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0 |
Prompt To Fix With AI
This is a comment left during a code review.
Path: CHANGELOG.md
Line: 228-229
Comment:
The `[1.15.0]` reference link is missing from the footer, so the `## [1.15.0]` heading in rendered Markdown is not a clickable link. The `[Unreleased]` compare URL also still points to `v1.14.0` instead of the just-released `v1.15.0`.
```suggestion
[Unreleased]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/compare/v1.15.0...HEAD
[1.15.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.15.0
[1.14.0]: https://github.com/DojoCodingLabs/make-no-mistakes-toolkit/releases/tag/v1.14.0
```
How can I resolve this? If you propose a fix, please make it concise.Warns when a version manifest (package.json, plugin.json, marketplace.json, or their .claude-plugin/ namespaced variants) is being bumped without a parallel update to README.md + CHANGELOG.md. This closes the gap PR #21 exposed: the toolkit shipped 1.1.0 -> 1.14.0 with no visible version surface (no README line, no CHANGELOG, no git tags). Without an enforcement rule, the same drift will reappear on the next bump. Pattern (DOJ-4064 three-layer drift thesis, Cure 4 - PreToolUse hooks): - Triggers on Write/Edit/MultiEdit to package.json, plugin.json, marketplace.json, .claude-plugin/plugin.json, .claude-plugin/marketplace.json - Detects new `"version": "X.Y.Z"` field in the written content / new_string - Warns the agent to update README.md "Version:" line + CHANGELOG.md entry in the same change - Tier 2 (warn, non-blocking) - hook cannot see other files in the diff, so it nudges rather than enforces - Bypass marker: version-readme-changelog-sync Sister enforcement (defense-in-depth): the dojo-os repo ships its own PostToolUse hook (.claude/hooks/post-write-version-readme-sync.sh) that catches the same drift locally even when the toolkit isn't installed. 11 new tests, all pass. Total rules: 32 (was 31). Created by Claude Code on behalf of @andres. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Coordinated bump across the four version surfaces: - package.json 1.14.0 -> 1.15.0 - .claude-plugin/plugin.json 1.14.0 -> 1.15.0 - .claude-plugin/marketplace.json 1.14.0 -> 1.15.0 (top + nested) - README.md "Version: ..." line 1.14.0 -> 1.15.0 This is the first bump that dogfoods the warn-version-readme-changelog-sync rule shipped in the prior commit on this branch: every manifest write would now warn about the README/CHANGELOG update requirement. README is being updated in this same commit; CHANGELOG entry follows in the next commit. Created by Claude Code on behalf of @andres. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Adds the 1.15.0 section to CHANGELOG.md immediately above the existing 1.14.0 entry, documenting: - The new warn-version-readme-changelog-sync Tier 2 rule (32 rules total) - The defense-in-depth pattern (toolkit + dojo-os parallel PRs) - The dogfooding observation: this release ships via the rule it adds This is the third atomic commit of the PR: 1. feat(rules): add the rule (commit 5dd0a67) 2. chore: bump to 1.15.0 across manifests + README (commit c9469f0) 3. docs(changelog): add 1.15.0 entry (this commit) Together they demonstrate the full discipline the rule enforces: manifest + README + CHANGELOG all updated in lockstep within the same PR. Created by Claude Code on behalf of @andres. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
babb67e to
06c185f
Compare
Gap this closes
PR #21 closed the visible-version gap by reconstructing
CHANGELOG.mdand adding aVersion:line toREADME.md. This PR adds the enforcement rule that prevents the gap from reopening on the next manifest bump — and dogfoods it by shipping itself via the new rule.Without an automated rule, every future
package.json/plugin.json/marketplace.jsonversion bump would silently re-introduce the same drift PR #21 fixed.What ships
1. New Tier 2 rule:
warn-version-readme-changelog-syncTriggers on:
Write/Edit/MultiEditto any of:package.jsonplugin.json(root-level)marketplace.json(root-level).claude-plugin/plugin.json.claude-plugin/marketplace.jsonMatch condition: content /
new_stringcontains"version": "X.Y.Z"Action:
warn(non-blocking — the hook can only see one file at a time, so it nudges rather than enforces)Bypass marker:
version-readme-changelog-sync11 new tests, all pass. Total: 32 rules / 210 tests (was 31 / 199).
2. Version bump to 1.15.0 across all four surfaces
package.json.claude-plugin/plugin.json.claude-plugin/marketplace.json(top + nested)README.md(`Version:` line)3. CHANGELOG.md entry under
## [1.15.0] - 2026-05-14Documents the new rule, the defense-in-depth pattern, and the dogfooding observation: this release ships via the rule it adds.
Defense-in-depth pattern (DOJ-4064 thesis)
This is the cross-repo half of a two-PR defense-in-depth implementation:
.claude/hooks/post-write-version-readme-sync.shenforces the same invariant in dojo-os even if this toolkit isn't installed.Both layers catch the same drift; neither alone is sufficient.
Sister PR in dojo-os: `andres/doj-readme-version-and-version-sync-hook` (opened in parallel — links back here in its body).
Stack note
This PR is stacked on top of PR #21 (`andres/toolkit-readme-version-and-changelog`), which adds the README `Version:` line and reconstructs CHANGELOG.md. PR #21 must merge first; this PR then auto-rebases onto `main`.
Commits (atomic)
Verification
Hard constraints honoured
--no-verifyon any commit (let lefthook run).DO NOT MERGE
Andrés will review and merge. HITL gate.
Created by Claude Code on behalf of @andres.