@windyroad/voice-tone 0.5.13 → 0.5.14-preview.746

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.
@@ -123,5 +123,5 @@
123
123
  }
124
124
  },
125
125
  "name": "wr-voice-tone",
126
- "version": "0.5.13"
126
+ "version": "0.5.14"
127
127
  }
@@ -23,3 +23,11 @@ EXTERNAL_COMMS_POLICY_FILE=docs/VOICE-AND-TONE.md
23
23
  # concern (run by packages/risk-scorer/hooks/external-comms-gate.sh when that
24
24
  # plugin is also installed).
25
25
  EXTERNAL_COMMS_LEAK_PREFILTER=no
26
+
27
+ # Surfaces this evaluator's policy doc disclaims — the gate silent-passes the
28
+ # marker-review delegation on them (P360). docs/VOICE-AND-TONE.md § Scope
29
+ # excludes commit messages ("It does NOT apply to: ... Commit messages (covered
30
+ # by ADR-014 + ADR-018)"), so a voice-tone review of the git-commit-message
31
+ # surface is a guaranteed-PASS no-op (~19K tokens). Skip it. The risk evaluator
32
+ # does NOT skip this surface — its leak check on commit bodies is meaningful.
33
+ EXTERNAL_COMMS_SKIP_SURFACES=git-commit-message
@@ -78,6 +78,10 @@ source "$SCRIPT_DIR/lib/external-comms-key.sh"
78
78
  # EXTERNAL_COMMS_ASSESS_SKILL — on-demand skill path for manual delegation
79
79
  # EXTERNAL_COMMS_POLICY_FILE — policy doc whose absence triggers advisory-only
80
80
  # EXTERNAL_COMMS_LEAK_PREFILTER — yes|no — whether to run leak-detect pre-filter
81
+ # EXTERNAL_COMMS_SKIP_SURFACES — space-separated surface list this evaluator's
82
+ # policy disclaims; the marker-review delegation
83
+ # silent-passes on those surfaces (P360). Default
84
+ # empty (gate every detected surface).
81
85
  # Fail-closed if absent: this hook cannot operate without a configured evaluator.
82
86
  CONF_FILE="$SCRIPT_DIR/external-comms-evaluator.conf"
83
87
  if [ ! -f "$CONF_FILE" ]; then
@@ -91,6 +95,7 @@ source "$CONF_FILE"
91
95
  : "${EXTERNAL_COMMS_ASSESS_SKILL:?assess-skill missing from $CONF_FILE}"
92
96
  EXTERNAL_COMMS_POLICY_FILE="${EXTERNAL_COMMS_POLICY_FILE:-RISK-POLICY.md}"
93
97
  EXTERNAL_COMMS_LEAK_PREFILTER="${EXTERNAL_COMMS_LEAK_PREFILTER:-yes}"
98
+ EXTERNAL_COMMS_SKIP_SURFACES="${EXTERNAL_COMMS_SKIP_SURFACES:-}"
94
99
 
95
100
  # ---------- Bypass ----------
96
101
  if [ "${BYPASS_RISK_GATE:-0}" = "1" ]; then
@@ -318,6 +323,26 @@ if [ "$EXTERNAL_COMMS_LEAK_PREFILTER" = "yes" ]; then
318
323
  fi
319
324
  fi
320
325
 
326
+ # ---------- Per-evaluator surface skip (P360) ----------
327
+ # Some surfaces are explicitly disclaimed by THIS evaluator's policy doc, so the
328
+ # marker-review delegation below would be a guaranteed-PASS no-op (the subagent
329
+ # reads the policy, declares the surface out of scope, emits PASS — ~19K tokens
330
+ # per round-trip). EXTERNAL_COMMS_SKIP_SURFACES (per-package .conf) lists those
331
+ # surfaces; the gate silent-passes the prose-review delegation when the detected
332
+ # surface is on the list. Voice-tone sets this to `git-commit-message` because
333
+ # docs/VOICE-AND-TONE.md § Scope excludes commit messages ("covered by ADR-014 +
334
+ # ADR-018"); risk-scorer leaves it empty (its leak check on commit messages is
335
+ # meaningful). Placed AFTER the leak pre-filter so a skipped surface still gets
336
+ # credential/prod-URL scanning — this silences ONLY the prose-review deny, the
337
+ # same conservative shape as the P365 repo-visibility precondition below.
338
+ if [ -n "$EXTERNAL_COMMS_SKIP_SURFACES" ]; then
339
+ case " $EXTERNAL_COMMS_SKIP_SURFACES " in
340
+ *" $SURFACE "*)
341
+ exit 0
342
+ ;;
343
+ esac
344
+ fi
345
+
321
346
  # ---------- Repo-visibility precondition: git-commit-message surface (P365) ----------
322
347
  # A commit message only becomes external-facing prose when it lands in a PUBLIC
323
348
  # GitHub repo (git log / PR commits tab / release-page auto-notes / CHANGELOG).
@@ -247,143 +247,113 @@ run_hook() {
247
247
  }
248
248
 
249
249
  # ---------------------------------------------------------------------------
250
- # P082 Phase 1 git commit message surface (voice-tone evaluator).
251
- # Commit messages reach git log / PR commits tab / release notes / CHANGELOG;
252
- # voice-tone evaluator gates the message body for AI-tells, hedging,
253
- # em-dashes, banned-phrase drift before the commit lands. Editor flow
254
- # (bare `git commit`) is out of scope per P082 SC1 — the message is
255
- # written to .git/COMMIT_EDITMSG AFTER PreToolUse fires.
250
+ # P360 voice-tone evaluator disclaims the git-commit-message surface.
251
+ # docs/VOICE-AND-TONE.md § Scope explicitly excludes commit messages ("It does
252
+ # NOT apply to: ... Commit messages (covered by ADR-014 + ADR-018)"), so a
253
+ # voice-tone review of a commit-message body is a guaranteed-PASS no-op
254
+ # (~19K tokens per round-trip). external-comms-evaluator.conf sets
255
+ # EXTERNAL_COMMS_SKIP_SURFACES=git-commit-message, so the gate silent-passes the
256
+ # prose-review delegation on this surface in EVERY repo — visibility-independent
257
+ # (the P360 skip is placed ahead of the P365 visibility precondition). The
258
+ # risk-scorer evaluator, whose .conf leaves the skip list empty, still gates
259
+ # this surface (its leak check is meaningful) — covered by
260
+ # packages/risk-scorer/hooks/test/external-comms-gate.bats.
261
+ #
262
+ # Supersedes the original P082 Phase 1 voice-tone commit-message tests, which
263
+ # asserted DENY on PUBLIC — that gate fire was the no-op P360 removes.
256
264
  # ---------------------------------------------------------------------------
257
265
 
258
- @test "P082: git commit -m with literal -m body denies and delegates to voice-tone evaluator" {
266
+ @test "P360: git commit -m silent-passes (voice-tone disclaims commit messages)" {
259
267
  mock_gh_visibility PUBLIC
260
268
  INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
261
269
  run_hook "$INPUT"
262
270
  [ "$status" -eq 0 ]
263
- [[ "$output" == *"deny"* ]]
264
- [[ "$output" == *"git-commit-message"* ]]
265
- [[ "$output" == *"wr-voice-tone:external-comms"* ]]
271
+ [ -z "$output" ]
266
272
  }
267
273
 
268
- @test "P082: git commit --message with literal body denies and delegates" {
274
+ @test "P360: git commit --message silent-passes with no marker round-trip" {
269
275
  mock_gh_visibility PUBLIC
270
276
  INPUT=$(build_bash_input "git commit --message \"happy to help further with this fix\"")
271
277
  run_hook "$INPUT"
272
278
  [ "$status" -eq 0 ]
273
- [[ "$output" == *"deny"* ]]
274
- [[ "$output" == *"git-commit-message"* ]]
279
+ [ -z "$output" ]
275
280
  }
276
281
 
277
- @test "P082: git commit --amend -m is intercepted (P082 SC2)" {
282
+ @test "P360: git commit --amend -m silent-passes" {
278
283
  mock_gh_visibility PUBLIC
279
284
  INPUT=$(build_bash_input "git commit --amend -m \"rewritten subject\"")
280
285
  run_hook "$INPUT"
281
286
  [ "$status" -eq 0 ]
282
- [[ "$output" == *"deny"* ]]
283
- [[ "$output" == *"git-commit-message"* ]]
287
+ [ -z "$output" ]
284
288
  }
285
289
 
286
- @test "P082: git commit HEREDOC body is intercepted and the body becomes the marker key" {
287
- # Build a HEREDOC-shaped command. The hook regex pulls the body BETWEEN
288
- # the <<'EOF' opener and the closing EOF marker — the extracted DRAFT is
289
- # the inner text, NOT the literal `$(cat <<'EOF' ... EOF)` wrapper.
290
+ @test "P360: git commit HEREDOC body silent-passes without a marker" {
290
291
  mock_gh_visibility PUBLIC
291
292
  BODY=$'feat(foo): add bar\n\nWe observed a build failure on Node 20.'
292
293
  CMD=$'git commit -m "$(cat <<\'EOF\'\n'"$BODY"$'\nEOF\n)"'
293
294
  INPUT=$(build_bash_input "$CMD")
294
295
  run_hook "$INPUT"
295
296
  [ "$status" -eq 0 ]
296
- [[ "$output" == *"deny"* ]]
297
- [[ "$output" == *"git-commit-message"* ]]
298
-
299
- # Pre-place the per-evaluator marker keyed on the extracted HEREDOC body
300
- # + the git-commit-message surface; the second run must permit silently.
301
- SURFACE="git-commit-message"
302
- KEY=$(printf '%s\n%s' "$BODY" "$SURFACE" | shasum -a 256 | cut -d' ' -f1)
303
- touch "${RDIR}/external-comms-voice-tone-reviewed-${KEY}"
304
- run_hook "$INPUT"
305
- [ "$status" -eq 0 ]
306
297
  [ -z "$output" ]
307
298
  }
308
299
 
309
- @test "P082: bare git commit (editor flow) is silently allowed per SC1" {
310
- # No -m / --message → .git/COMMIT_EDITMSG doesn't exist at PreToolUse
311
- # time. Phase 1 skip is pragmatic; the editor flow has user-eyeballs.
312
- INPUT=$(build_bash_input "git commit")
300
+ @test "P360: commit-message skip is visibility-independent (PRIVATE silent-passes)" {
301
+ mock_gh_visibility PRIVATE
302
+ INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
313
303
  run_hook "$INPUT"
314
304
  [ "$status" -eq 0 ]
315
305
  [ -z "$output" ]
316
306
  }
317
307
 
318
- @test "P082: git merge is silently allowed (not a git commit verb)" {
319
- INPUT=$(build_bash_input "git merge --no-ff feature-branch")
308
+ @test "P360: commit-message skip is visibility-independent (INTERNAL silent-passes)" {
309
+ mock_gh_visibility INTERNAL
310
+ INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
320
311
  run_hook "$INPUT"
321
312
  [ "$status" -eq 0 ]
322
313
  [ -z "$output" ]
323
314
  }
324
315
 
325
- @test "P082: BYPASS_RISK_GATE=1 short-circuits the git commit gate" {
316
+ @test "P360: commit-message skip is visibility-independent (indeterminate gh silent-passes)" {
317
+ mock_gh_visibility FAIL
326
318
  INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
327
- run bash -c "cd '$TEST_PROJECT_DIR' && BYPASS_RISK_GATE=1 printf '%s' \"\$1\" | BYPASS_RISK_GATE=1 '$HOOK'" _ "$INPUT"
328
- [ "$status" -eq 0 ]
329
- [ -z "$output" ]
330
- }
331
-
332
- @test "P082: per-evaluator marker keyed on (body, git-commit-message) permits the call" {
333
- mock_gh_visibility PUBLIC
334
- BODY="docs(retro): close iter 3 ask-hygiene trail"
335
- SURFACE="git-commit-message"
336
- KEY=$(printf '%s\n%s' "$BODY" "$SURFACE" | shasum -a 256 | cut -d' ' -f1)
337
- touch "${RDIR}/external-comms-voice-tone-reviewed-${KEY}"
338
-
339
- INPUT=$(build_bash_input "git commit -m \"$BODY\"")
340
319
  run_hook "$INPUT"
341
320
  [ "$status" -eq 0 ]
342
321
  [ -z "$output" ]
343
322
  }
344
323
 
345
- # ---------------------------------------------------------------------------
346
- # P365 — repo-visibility precondition on the git-commit-message surface.
347
- # Shared canonical hook (ADR-017 sync), so the precondition applies to the
348
- # voice-tone evaluator too: a commit message is external-facing prose ONLY in
349
- # a PUBLIC repo. In private/internal repos — or any indeterminate gh result —
350
- # the marker-review deny is a pure false-positive (user direction 2026-06-11:
351
- # "this MUST NOT fire for private repos"). Scoped to the git-commit-message
352
- # surface only; the gh-issue/pr/npm/changeset surfaces are inherently external
353
- # and stay gated regardless of repo visibility.
354
- # ---------------------------------------------------------------------------
355
-
356
- @test "P365: git commit -m in a PRIVATE repo silent-passes (no external-comms deny)" {
357
- mock_gh_visibility PRIVATE
358
- INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
324
+ @test "P082: bare git commit (editor flow) is silently allowed per SC1" {
325
+ # No -m / --message .git/COMMIT_EDITMSG doesn't exist at PreToolUse
326
+ # time. Phase 1 skip is pragmatic; the editor flow has user-eyeballs.
327
+ INPUT=$(build_bash_input "git commit")
359
328
  run_hook "$INPUT"
360
329
  [ "$status" -eq 0 ]
361
330
  [ -z "$output" ]
362
331
  }
363
332
 
364
- @test "P365: git commit -m in an INTERNAL repo silent-passes" {
365
- mock_gh_visibility INTERNAL
366
- INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
333
+ @test "P082: git merge is silently allowed (not a git commit verb)" {
334
+ INPUT=$(build_bash_input "git merge --no-ff feature-branch")
367
335
  run_hook "$INPUT"
368
336
  [ "$status" -eq 0 ]
369
337
  [ -z "$output" ]
370
338
  }
371
339
 
372
- @test "P365: git commit -m when gh is unavailable/indeterminate silent-passes (fail-non-public)" {
373
- mock_gh_visibility FAIL
340
+ @test "P082: BYPASS_RISK_GATE=1 short-circuits the git commit gate" {
374
341
  INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
375
- run_hook "$INPUT"
342
+ run bash -c "cd '$TEST_PROJECT_DIR' && BYPASS_RISK_GATE=1 printf '%s' \"\$1\" | BYPASS_RISK_GATE=1 '$HOOK'" _ "$INPUT"
376
343
  [ "$status" -eq 0 ]
377
344
  [ -z "$output" ]
378
345
  }
379
346
 
380
- @test "P365: git commit -m in a PUBLIC repo still denies+delegates (gate intact, precondition surface-scoped)" {
347
+ @test "P360: the skip is surface-scoped gh-issue is NOT skipped (still denies+delegates)" {
348
+ # EXTERNAL_COMMS_SKIP_SURFACES lists only git-commit-message; the inherently
349
+ # external gh-issue surface stays gated. Guards against the skip list over-
350
+ # matching (e.g. a substring or blanket-skip regression).
381
351
  mock_gh_visibility PUBLIC
382
- INPUT=$(build_bash_input "git commit -m \"I've implemented the feature\"")
352
+ INPUT=$(build_bash_input "gh issue create --title x --body 'a clean issue body'")
383
353
  run_hook "$INPUT"
384
354
  [ "$status" -eq 0 ]
385
355
  [[ "$output" == *"deny"* ]]
386
- [[ "$output" == *"git-commit-message"* ]]
356
+ [[ "$output" == *"wr-voice-tone:external-comms"* ]]
387
357
  }
388
358
 
389
359
  @test "P365: PRIVATE visibility does NOT short-circuit the gh-issue surface (still denies+delegates)" {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/voice-tone",
3
- "version": "0.5.13",
3
+ "version": "0.5.14-preview.746",
4
4
  "description": "Voice and tone enforcement for user-facing copy",
5
5
  "bin": {
6
6
  "windyroad-voice-tone": "./bin/install.mjs"