@windyroad/risk-scorer 0.15.1 → 0.15.2-preview.884
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.
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
|
@@ -211,6 +211,44 @@ run_hook() {
|
|
|
211
211
|
[[ "$output" == *"wr-risk-scorer:external-comms"* ]]
|
|
212
212
|
}
|
|
213
213
|
|
|
214
|
+
# ---------------------------------------------------------------------------
|
|
215
|
+
# P405 — read-only `gh api` polls must NOT trip the gate. `gh api` defaults to
|
|
216
|
+
# GET; it only carries an outbound prose body (the thing this gate reviews)
|
|
217
|
+
# when a request-body flag (-f/--field, -F/--raw-field, --input) is present.
|
|
218
|
+
# The `/wr-itil:review-problems` Step 4.5c security-advisories discovery poll
|
|
219
|
+
# is read-only (`--jq` filter, no body flag) and was being denied as if it
|
|
220
|
+
# were an advisory draft, silently blacking out one discovery channel.
|
|
221
|
+
# ---------------------------------------------------------------------------
|
|
222
|
+
|
|
223
|
+
@test "P405: read-only gh api security-advisories poll (--jq, no body flag) is not gated" {
|
|
224
|
+
INPUT=$(build_bash_input "gh api repos/foo/bar/security-advisories --jq '.[].ghsa_id'")
|
|
225
|
+
run_hook "$INPUT"
|
|
226
|
+
[ "$status" -eq 0 ]
|
|
227
|
+
[ -z "$output" ]
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@test "P405: bare gh api security-advisories read (no flags) is not gated" {
|
|
231
|
+
INPUT=$(build_bash_input "gh api repos/foo/bar/security-advisories")
|
|
232
|
+
run_hook "$INPUT"
|
|
233
|
+
[ "$status" -eq 0 ]
|
|
234
|
+
[ -z "$output" ]
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
@test "P405: read-only gh api comments poll (--jq, no body flag) is not gated" {
|
|
238
|
+
INPUT=$(build_bash_input "gh api repos/foo/bar/issues/1/comments --jq '.[].body'")
|
|
239
|
+
run_hook "$INPUT"
|
|
240
|
+
[ "$status" -eq 0 ]
|
|
241
|
+
[ -z "$output" ]
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
@test "P405: gh api security-advisories write with -f body flag still triggers the gate" {
|
|
245
|
+
INPUT=$(build_bash_input "gh api repos/foo/bar/security-advisories -f summary='new advisory'")
|
|
246
|
+
run_hook "$INPUT"
|
|
247
|
+
[ "$status" -eq 0 ]
|
|
248
|
+
[[ "$output" == *"deny"* ]]
|
|
249
|
+
[[ "$output" == *"wr-risk-scorer:external-comms"* ]]
|
|
250
|
+
}
|
|
251
|
+
|
|
214
252
|
@test "npm publish triggers the gate" {
|
|
215
253
|
INPUT=$(build_bash_input "npm publish")
|
|
216
254
|
run_hook "$INPUT"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windyroad/risk-scorer",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.2-preview.884",
|
|
4
4
|
"description": "Pipeline risk scoring, commit/push gates, and secret leak detection",
|
|
5
5
|
"bin": {
|
|
6
6
|
"windyroad-risk-scorer": "./bin/install.mjs"
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
".claude-plugin/",
|
|
27
27
|
"lib/",
|
|
28
28
|
"scripts/",
|
|
29
|
-
"!skills/*/eval/"
|
|
29
|
+
"!skills/*/eval/",
|
|
30
|
+
"!agents/eval/"
|
|
30
31
|
]
|
|
31
32
|
}
|