8266755c2e
The verify-before-push hook now skips the regression gate when EVERY
staged/unpushed file is a .md document (memory, docs, specs, plans,
SKILL.md). Code-touching pushes remain fully gated as before; mixed
pushes (even one non-md file) keep the full gate.
Closes the recurring loop where Claude invokes the "ремонт инфраструктуры"
override on every docs-only push — regression adds no value when the
change set has no executable code.
New helpers (tools/enforce-hook-helpers.mjs):
- isDocsOnlyPath(p): true iff path ends with .md (case-insensitive)
- isDocsOnlyChange(paths): true iff non-empty AND every entry docs-only
- listChangedFiles(kind): git diff --cached (commit) / @{u}..HEAD (push)
Empty result = unknown -> caller MUST fall through to normal gate.
decide() in enforce-verify-before-push.mjs accepts a new changedPaths
arg and short-circuits {block: false} when isDocsOnlyChange === true.
Empty/undefined -> falls through (conservative).
TDD: 13 new tests across enforce-hook-helpers.test.mjs + enforce-verify-
before-push.test.mjs, all GREEN. Tools-only canonical regression 965/965.