Skip to content

0.3.2: fix comment-guard false positives (DEV-28/41/43/49, DEV-57) - #1

Merged
TAJD merged 7 commits into
mainfrom
dev-28-41-43-49-comment-guard-cluster
Sep 6, 2026
Merged

TAJD merged 7 commits into
mainfrom
dev-28-41-43-49-comment-guard-cluster

Conversation

@TAJD

@TAJD TAJD commented Sep 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • DEV-41: regex literals with / no longer misdetected as // comments; bare-token HTML comments (<!--app-head-->) treated as placeholders, not prose.
  • DEV-43: Bash commands that are entirely git checkout/switch/mv/restore/merge/rebase/cherry-pick/pull/reset/stash apply|pop skip the snapshot/audit — they change working-tree content without the agent authoring anything.
  • DEV-28: Write to a brand-new file is no longer denied outright for any comment — if every added comment line's text exists elsewhere in the repo's HEAD tree, it's treated as moved.
  • DEV-49: Edit/Write/MultiEdit no longer deny restoring a comment still present in the file's HEAD-committed blob.
  • DEV-57: closes the general case DEV-43 only partly covered. The post-Bash audit now tracks the git worktree root and HEAD at snapshot time and skips the audit (no block, just a skip-tree-moved log line) if either has moved by the time the command finishes. This catches two false-positive classes DEV-43's plumbing-only fast path missed: (1) a command that cds into a different worktree (linked worktrees share the object database, so the cross-worktree diff resolves without erroring and blames that worktree's pre-existing comments on the command), and (2) a compound command mixing git checkout/fetch with a non-plumbing verb like git status, which isn't "plumbing-only" so previously fell through to a full audit against the new HEAD. A same-repo, same-HEAD genuine comment addition still blocks as before — verified with a dedicated regression test.

Test plan

  • npm test — 153/153 passing (3 new DEV-57 regression tests: cross-worktree cd suppressed, mixed-command HEAD-move suppressed, genuine same-HEAD addition still blocks)
  • Verified no regressions in the 150 pre-existing tests

HUMAN CHECK

  1. Run npm test from a checkout of this branch — expect # pass 153, # fail 0.
  2. Least confident about: the regex-literal heuristic (REGEX_LITERAL_RE) is a best-effort lookbehind, not a real JS parser — it can misclassify an unusual division expression as a regex literal in rare cases (this only risks a false negative, not a new false-positive block).
  3. DEV-57's fix compares git root + HEAD only, not the working tree's dirty state — a command that leaves HEAD and root unchanged but stages/unstages files independent of the command won't be caught by this particular check (unrelated to the reported bug; audit still runs and behaves as before in that case).
  4. To revert: git revert 218f4f4 — it's a single self-contained commit on top of 0.3.1's fixes. No hook config or settings.json changes are involved, so reverting only requires updating this plugin's installed version.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM

TAJD and others added 6 commits September 6, 2026 08:44
…guard

- Regex literals with `/` no longer misdetected as `//` comments (DEV-41).
- Bare-token HTML comments (`<!--app-head-->`) are template placeholders,
  not prose, and are exempted; prose HTML comments still count (DEV-41).
- Bash commands that are entirely git checkout/switch/mv/restore/merge/
  rebase/cherry-pick/pull/reset/stash apply|pop skip the snapshot/audit
  entirely, since they change working-tree content without the agent
  authoring anything (DEV-43).
- A Write to a brand-new file is no longer denied outright for any
  comment: if every added comment line's text also exists elsewhere in
  the repo's HEAD tree, it's treated as moved, not authored (DEV-28).
- Edit/Write/MultiEdit no longer deny restoring a comment that still
  exists in the file's HEAD-committed blob (DEV-49).

150 tests passing (21 new).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
…ests

PR #1's Windows/macOS CI runs intermittently failed the new
"restoring a comment still present in HEAD is allowed" test with the
hook denying instead of allowing. Root cause: node --test runs test
files (bash.test.mjs, hook.test.mjs) concurrently by default, and both
spin up many temporary git repos; under CI/AV load the git subprocess
timeout in gitOut() (4s) was occasionally exceeded, making
headBlobFor() silently fail (fails-open to the deny path). Raised the
timeout to 10s (matching the existing snapshot-audit timeout) and
pinned test-concurrency=1 to remove the concurrent-git-process
contention this exposed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
git show HEAD:<path> returns CRLF-converted text on Windows/macOS
runners when core.autocrlf is set, which never matched the LF-only
edit text compared against it in relaxForMovedOrRestoredComments.
This deterministically failed the "restoring a comment still present
in HEAD is allowed" test on windows-latest/macos-latest CI while
passing on ubuntu-latest. Reuse the existing normalise() helper
(already used for the same class of problem elsewhere in this file).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
GitHub Actions Windows runners expose the temp directory through an
8.3 short-name path segment (RUNNER~1) in some contexts. If git's
rev-parse --show-toplevel and Node's resolve(path) disagree on long
vs short form for the same directory, relative() computes garbage,
git show fails, headBlobFor returns null, and the restore-from-HEAD
relaxation never engages. Route both sides through realpathSync
(falling back to the original value if it throws) so they agree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
Diagnostic only, to be reverted once the root cause of the
Windows-only 'restoring a comment still present in HEAD' failure
is confirmed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
…h math

Root cause confirmed via a temporary CI debug step (now reverted):
on GitHub's windows-latest runner, mkdtempSync()/resolve() return the
temp path through its 8.3 short name (C:\Users\RUNNER~1\...), while
git rev-parse --show-toplevel returns the canonicalized long form
(C:/Users/runneradmin/...). Node's realpathSync does not expand
Windows 8.3 short names, so relative(root, resolve(path)) produced
a bogus path that fell outside the repo, git show failed, and the
restore-from-HEAD relaxation silently never engaged.

Fix: never mix a Node-resolved path with a git-resolved one. Ask
git itself for the file's repo-relative prefix (git rev-parse
--show-prefix, run from the file's own directory) and append the
basename, so the whole computation stays inside git's own path
resolution.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
The post-Bash audit diffed the pre-command git-tree snapshot against
whatever the cwd's working tree looked like afterward. If a command cd'd
into a different worktree (linked worktrees share the object database, so
the diff resolves without error), or ran git checkout/fetch mixed with a
non-plumbing verb like git status (falling outside the existing
plumbing-only fast path), the audit compared unrelated trees and blamed
the command for pre-existing, human-authored comments it never touched.

Track the git root and HEAD at snapshot time and skip the audit (logging
skip-tree-moved, not blocking) if either has moved by post-command time.
A same-repo, same-HEAD genuine comment addition still blocks as before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EAvmyrEwiqgQhbaA3w4TsM
@TAJD TAJD changed the title 0.3.1: fix comment-guard false positives (DEV-28/41/43/49) 0.3.2: fix comment-guard false positives (DEV-28/41/43/49, DEV-57) Sep 6, 2026
@TAJD
TAJD merged commit e042ca8 into main Sep 6, 2026
7 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.

1 participant