@windyroad/risk-scorer 0.14.3 → 0.15.0

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.
@@ -310,5 +310,5 @@
310
310
  }
311
311
  },
312
312
  "name": "wr-risk-scorer",
313
- "version": "0.14.3"
313
+ "version": "0.15.0"
314
314
  }
@@ -41,10 +41,23 @@ PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
41
41
  POLICY_FILE="$PROJECT_DIR/RISK-POLICY.md"
42
42
  REGISTER_DIR="$PROJECT_DIR/docs/risks"
43
43
 
44
- # Silent when the project does not have a risk policy. The policy file
45
- # presence is the user authorisation for the register to exist; without
46
- # it, the absence of docs/risks/ is not a governance gap.
47
- [ -f "$POLICY_FILE" ] || exit 0
44
+ # Silent when the project dir itself does not exist no adopter project
45
+ # to nudge (e.g. a stale CLAUDE_PROJECT_DIR).
46
+ [ -d "$PROJECT_DIR" ] || exit 0
47
+
48
+ # Policy file absent entirely (P379, inverse predicate of the
49
+ # register-missing arm below). Without a RISK-POLICY.md the risk-scorer
50
+ # gates run at their default appetite (5 per ADR-086) silently, and the
51
+ # capability sits dormant with no surfacing that a policy can be authored.
52
+ # Nudge the adopter to author one via /wr-risk-scorer:update-policy. The
53
+ # original guard treated bare policy-absence as a non-gap; the P379 review
54
+ # (ADR-047 Amendment 2026-06-28) records the predicate reversal. Read-only
55
+ # — the hook never writes; the policy authoring is gated behind the user
56
+ # invoking the on-demand skill.
57
+ if [ ! -f "$POLICY_FILE" ]; then
58
+ echo "[wr-risk-scorer] No RISK-POLICY.md in this project — run /wr-risk-scorer:update-policy to author one so the risk-scorer gates score against your appetite instead of the default."
59
+ exit 0
60
+ fi
48
61
 
49
62
  # Register directory missing — nudge to scaffold it.
50
63
  if [ ! -d "$REGISTER_DIR" ]; then
@@ -13,6 +13,11 @@
13
13
  # pending-review backlog self-surfaces (class-B) instead of rotting
14
14
  # silently once stubs exist (the audit's "one step short of the jtbd
15
15
  # pattern" gap).
16
+ #
17
+ # P379 (2026-06-28): inverse predicate of the register-missing arm — when
18
+ # RISK-POLICY.md is ABSENT ENTIRELY the hook nudges the adopter to author
19
+ # one via /wr-risk-scorer:update-policy (the gates otherwise run at the
20
+ # default appetite silently). Same AFK-suppress envelope (ADR-068).
16
21
  # Behavioural — exercises the hook against fixture trees and asserts on stdout.
17
22
 
18
23
  setup() {
@@ -20,6 +25,11 @@ setup() {
20
25
  HOOK="$REPO_ROOT/packages/risk-scorer/hooks/risk-scorer-scaffold-nudge.sh"
21
26
  PLUGIN_ROOT="$REPO_ROOT/packages/risk-scorer"
22
27
  DIR="$(mktemp -d)"
28
+ # Hermeticity (P391): the AFK work-problems orchestrator exports
29
+ # WR_SUPPRESS_OVERSIGHT_NUDGE=1, which the hook self-suppresses on. Unset it so
30
+ # nudge-emitting tests assert real behaviour; guard-specific tests set it
31
+ # per-invocation via `run env WR_SUPPRESS_OVERSIGHT_NUDGE=...`.
32
+ unset WR_SUPPRESS_OVERSIGHT_NUDGE
23
33
  }
24
34
 
25
35
  teardown() {
@@ -81,16 +91,24 @@ teardown() {
81
91
  [ -z "$output" ]
82
92
  }
83
93
 
84
- @test "silent when RISK-POLICY.md is absent (no policy file = no register expectation)" {
94
+ @test "emits a policy-authoring nudge when RISK-POLICY.md is absent (P379 inverse predicate)" {
85
95
  run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
86
96
  [ "$status" -eq 0 ]
87
- [ -z "$output" ]
97
+ [[ "$output" == *"No RISK-POLICY.md"* ]]
98
+ [[ "$output" == *"/wr-risk-scorer:update-policy"* ]]
88
99
  }
89
100
 
90
- @test "silent when RISK-POLICY.md is absent even if docs/risks/ exists" {
101
+ @test "policy-absent nudge fires even when docs/risks/ exists (policy-absence wins, P379)" {
91
102
  mkdir -p "$DIR/docs/risks"
92
103
  run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
93
104
  [ "$status" -eq 0 ]
105
+ [[ "$output" == *"No RISK-POLICY.md"* ]]
106
+ [[ "$output" == *"/wr-risk-scorer:update-policy"* ]]
107
+ }
108
+
109
+ @test "AFK guard suppresses the policy-absent nudge too (P379)" {
110
+ run env WR_SUPPRESS_OVERSIGHT_NUDGE=1 CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
111
+ [ "$status" -eq 0 ]
94
112
  [ -z "$output" ]
95
113
  }
96
114
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/risk-scorer",
3
- "version": "0.14.3",
3
+ "version": "0.15.0",
4
4
  "description": "Pipeline risk scoring, commit/push gates, and secret leak detection",
5
5
  "bin": {
6
6
  "windyroad-risk-scorer": "./bin/install.mjs"
@@ -25,6 +25,7 @@
25
25
  "skills/",
26
26
  ".claude-plugin/",
27
27
  "lib/",
28
- "scripts/"
28
+ "scripts/",
29
+ "!skills/*/eval/"
29
30
  ]
30
31
  }