Commit Graph

10 Commits

Author SHA1 Message Date
Дмитрий b93e5af439 chore(brain-retro): export CHAIN_OUTCOME_BUCKETS + clean up redundant fs import (Phase 4 #2 review fixes)
Code-quality review of Task B (Phase 4) flagged two minor fixes:
- Export CHAIN_OUTCOME_BUCKETS for external consumers (test + future cuts)
  no longer hard-code bucket names.
- Replace fs.readFileSync via duplicate `import fs from 'fs'` with the
  already-imported named `readFileSync` in helpers test.

+1 regression test on the export.
2026-05-28 15:48:42 +03:00
Дмитрий a3f5f392cd feat(brain-retro): Cut 11 chain-hook effectiveness ledger + analyzer (Phase 4 #2) 2026-05-28 15:48:39 +03:00
Дмитрий 5eb2066524 feat(hooks): enforce-semgrep-security — block git commit when auth/billing/CSV/webhook in staged без Semgrep (Phase 4 #9) 2026-05-28 15:48:37 +03:00
Дмитрий 8266755c2e feat(enforce-verify-before-push): docs-only short-circuit
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.
2026-05-27 08:23:17 +03:00
Дмитрий 165f1ed993 fix(hooks): findOverrideAttempt + helpful diagnostic for silent-reject when justification missing. Resolves UX bug where enforce-verify-before-push silently rejected master overrides without justification line. Now emits explicit diagnostic. 132/132 hook tests green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> 2026-05-26 15:53:04 +03:00
Дмитрий 57a7f55bf1 fix(enforce): hole 7 — ремонт инфраструктуры requires justification line
Brain-retro #5 candidate C, hole 7: the 'ремонт инфраструктуры' phrase
suppressed ALL rule keys with no constraint. Now requires a 'ремонт: <what>'
line in the same prompt documenting the target.

enforce-override-vocab.json: added 'requires_justification: "ремонт:"' to
the entry.
enforce-hook-helpers.mjs findOverride(): honors requires_justification — when
set, the user prompt must contain '<prefix> <non-empty-text>' or the override
is rejected.
2026-05-26 11:23:19 +03:00
Дмитрий c7079ac8e4 fix(enforce-helpers): detectFullTestRun first-real-command approach (third iteration)
Previous segment-split approach still mis-detected because naive && split
also splits INSIDE quoted commit messages. A git commit with a body like
'... npx vitest run ...' produced a segment starting with vitest after split.

New approach: find FIRST real command (after skipping cd / env-prefix),
classify based on that. Anything after it is arguments / chained commands,
which don't change the kind. Hard guard rejects first-real ∈ {git, scp, ssh,
curl, cat, echo, grep, cp, mv, ...}.

Found live: my own commit message from the previous fix ('handles compound
commands like cd ... && npx vitest run') caused the verify-pass sentinel to
overwrite as fail. Test for this case in helpers.test.mjs.
2026-05-26 03:22:29 +03:00
Дмитрий bfa228197d fix(enforce-helpers): detectFullTestRun handles compound commands (segment-split)
Previous guard ("any \b(git|cat|echo)\s/ → null") was too aggressive: it
blocked legitimate compound test commands like `cd ... && npx vitest run`
or `npx vitest run && echo done`.

New approach: split on shell separators, examine each segment after stripping
env-prefix and `cd` prefix. A command is a test run iff some segment STARTS
with a recognised test-invocation token. Correctly handles both directions:
  - false-positive guard (commit message containing 'vitest run' → null)
  - false-negative fix (compound 'cd ... && vitest run' → vitest-full)

Live-caught by my own TDD-gate: prod-edit blocked, wrote tests first, RED
verified, then GREEN. 59/59 unit tests pass.
2026-05-26 03:13:41 +03:00
Дмитрий 982cd00678 fix(enforce): detectFullTestRun guard against false-positive on git/echo/cat strings 2026-05-25 18:35:08 +03:00
Дмитрий 76cb825331 feat(enforce): T1 — shared hook helpers + override vocab 2026-05-25 18:14:34 +03:00