@windyroad/voice-tone 0.6.2 → 0.6.3-preview.885

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.6.2"
126
+ "version": "0.6.3"
127
127
  }
@@ -125,6 +125,19 @@ except Exception:
125
125
  # Permit silently when session_id is absent; the gate cannot key a marker.
126
126
  [ -n "$SESSION_ID" ] || exit 0
127
127
 
128
+ # P405: `gh api` defaults to a read (GET). It only carries an outbound prose
129
+ # body — the thing this gate reviews — when a request-body flag is supplied
130
+ # (-f/--field, -F/--raw-field, --input; any of these flips gh api's default to
131
+ # POST). Read-only polls carry none — e.g. `/wr-itil:review-problems` Step 4.5c's
132
+ # security-advisories discovery poll `gh api repos/O/R/security-advisories --jq ...`
133
+ # — and must NOT trip the gate. Used to narrow the two `gh api` surfaces
134
+ # (security-advisories + comments) to writes only; every other surface
135
+ # (gh issue/pr create|comment|edit, npm publish, changeset, git commit) is
136
+ # inherently a write and stays gated unconditionally.
137
+ _gh_api_has_body() {
138
+ printf '%s' "$1" | grep -qE '(^|[[:space:]])(--field|--raw-field|--input|-f|-F)([[:space:]]|=)'
139
+ }
140
+
128
141
  # ---------- Surface detection ----------
129
142
  SURFACE=""
130
143
  DRAFT=""
@@ -153,9 +166,19 @@ except Exception:
153
166
  elif echo "$COMMAND" | grep -qE '(^|;|&&|\|\|)\s*gh pr edit(\s|$)'; then
154
167
  SURFACE="gh-pr-edit"
155
168
  elif echo "$COMMAND" | grep -qE 'gh api .*security-advisories'; then
156
- SURFACE="gh-api-security-advisories"
169
+ # P405: gate only advisory-DRAFT writes; read-only polls (no body flag) skip.
170
+ if _gh_api_has_body "$COMMAND"; then
171
+ SURFACE="gh-api-security-advisories"
172
+ else
173
+ exit 0
174
+ fi
157
175
  elif echo "$COMMAND" | grep -qE 'gh api .*/comments'; then
158
- SURFACE="gh-api-comments"
176
+ # P405: gate only comment-body writes; read-only polls (no body flag) skip.
177
+ if _gh_api_has_body "$COMMAND"; then
178
+ SURFACE="gh-api-comments"
179
+ else
180
+ exit 0
181
+ fi
159
182
  elif echo "$COMMAND" | grep -qE '(^|;|&&|\|\|)\s*npm publish(\s|$)'; then
160
183
  SURFACE="npm-publish"
161
184
  elif echo "$COMMAND" | grep -qE '(^|;|&&|\|\|)\s*git commit(\s|$)'; then
@@ -196,6 +196,44 @@ run_hook() {
196
196
  [[ "$output" == *"wr-voice-tone:external-comms"* ]]
197
197
  }
198
198
 
199
+ # ---------------------------------------------------------------------------
200
+ # P405 — read-only `gh api` polls must NOT trip the gate. `gh api` defaults to
201
+ # GET; it only carries an outbound prose body (the thing this gate reviews)
202
+ # when a request-body flag (-f/--field, -F/--raw-field, --input) is present.
203
+ # The `/wr-itil:review-problems` Step 4.5c security-advisories discovery poll
204
+ # is read-only (`--jq` filter, no body flag) and was being denied as if it
205
+ # were an advisory draft, silently blacking out one discovery channel.
206
+ # ---------------------------------------------------------------------------
207
+
208
+ @test "P405: read-only gh api security-advisories poll (--jq, no body flag) is not gated" {
209
+ INPUT=$(build_bash_input "gh api repos/foo/bar/security-advisories --jq '.[].ghsa_id'")
210
+ run_hook "$INPUT"
211
+ [ "$status" -eq 0 ]
212
+ [ -z "$output" ]
213
+ }
214
+
215
+ @test "P405: bare gh api security-advisories read (no flags) is not gated" {
216
+ INPUT=$(build_bash_input "gh api repos/foo/bar/security-advisories")
217
+ run_hook "$INPUT"
218
+ [ "$status" -eq 0 ]
219
+ [ -z "$output" ]
220
+ }
221
+
222
+ @test "P405: read-only gh api comments poll (--jq, no body flag) is not gated" {
223
+ INPUT=$(build_bash_input "gh api repos/foo/bar/issues/1/comments --jq '.[].body'")
224
+ run_hook "$INPUT"
225
+ [ "$status" -eq 0 ]
226
+ [ -z "$output" ]
227
+ }
228
+
229
+ @test "P405: gh api security-advisories write with -f body flag still triggers the gate" {
230
+ INPUT=$(build_bash_input "gh api repos/foo/bar/security-advisories -f summary='new advisory'")
231
+ run_hook "$INPUT"
232
+ [ "$status" -eq 0 ]
233
+ [[ "$output" == *"deny"* ]]
234
+ [[ "$output" == *"wr-voice-tone:external-comms"* ]]
235
+ }
236
+
199
237
  @test "npm publish triggers the gate" {
200
238
  INPUT=$(build_bash_input "npm publish")
201
239
  run_hook "$INPUT"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/voice-tone",
3
- "version": "0.6.2",
3
+ "version": "0.6.3-preview.885",
4
4
  "description": "Voice and tone enforcement for user-facing copy",
5
5
  "bin": {
6
6
  "windyroad-voice-tone": "./bin/install.mjs"