@windyroad/risk-scorer 0.12.8 → 0.13.0-preview.678
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.
package/hooks/hooks.json
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"hooks": {
|
|
3
|
+
"SessionStart": [
|
|
4
|
+
{ "matcher": "startup", "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-scorer-scaffold-nudge.sh" }] }
|
|
5
|
+
],
|
|
3
6
|
"UserPromptSubmit": [
|
|
4
7
|
{ "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/risk-score.sh" }] }
|
|
5
8
|
],
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# wr-risk-scorer — SessionStart hook (ADR-047 Amendment 2026-06-08, P297)
|
|
3
|
+
#
|
|
4
|
+
# Surfaces a one-line nudge when this project has a RISK-POLICY.md (the
|
|
5
|
+
# trigger condition for an ISO 31000 / ISO 27001 standing-risk register)
|
|
6
|
+
# but lacks the docs/risks/ directory the register lives in. The user
|
|
7
|
+
# scaffolds the register on-demand via /wr-risk-scorer:bootstrap-catalog
|
|
8
|
+
# (ADR-059); this hook is the discovery surface — it does NOT write.
|
|
9
|
+
#
|
|
10
|
+
# Read-only, side-effect-free. Modelled on
|
|
11
|
+
# packages/architect/hooks/architect-oversight-nudge.sh (ADR-066) and
|
|
12
|
+
# packages/jtbd/hooks/jtbd-oversight-nudge.sh (ADR-068). Per ADR-040 the
|
|
13
|
+
# SessionStart surface stays read-mostly — this hook does not write to
|
|
14
|
+
# the adopter tree; the scaffold write is gated behind the user
|
|
15
|
+
# invoking the on-demand skill.
|
|
16
|
+
#
|
|
17
|
+
# AFK self-suppress (JTBD-006 friction guard): AFK orchestrators set
|
|
18
|
+
# WR_SUPPRESS_OVERSIGHT_NUDGE=1 before spawning each `claude -p` iteration
|
|
19
|
+
# so this interactive scaffold-confirm nudge never fires into an
|
|
20
|
+
# absent-user subprocess. The suite-wide env var is established by
|
|
21
|
+
# ADR-068 — one suppress variable governs every oversight-class nudge,
|
|
22
|
+
# scaffold-class included. Only the literal "1" suppresses.
|
|
23
|
+
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
|
|
26
|
+
if [ "${WR_SUPPRESS_OVERSIGHT_NUDGE:-}" = "1" ]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
31
|
+
POLICY_FILE="$PROJECT_DIR/RISK-POLICY.md"
|
|
32
|
+
REGISTER_DIR="$PROJECT_DIR/docs/risks"
|
|
33
|
+
|
|
34
|
+
# Silent when the project does not have a risk policy. The policy file
|
|
35
|
+
# presence is the user authorisation for the register to exist; without
|
|
36
|
+
# it, the absence of docs/risks/ is not a governance gap.
|
|
37
|
+
[ -f "$POLICY_FILE" ] || exit 0
|
|
38
|
+
|
|
39
|
+
# Silent when the register directory already exists — the scaffold has
|
|
40
|
+
# either already happened or the user has populated it manually.
|
|
41
|
+
[ -d "$REGISTER_DIR" ] && exit 0
|
|
42
|
+
|
|
43
|
+
echo "[wr-risk-scorer] RISK-POLICY.md present but docs/risks/ is missing — run /wr-risk-scorer:bootstrap-catalog to scaffold the standing-risk register."
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# ADR-047 Amendment 2026-06-08 (P297): risk-scorer-scaffold-nudge.sh
|
|
4
|
+
# (SessionStart) emits a one-line nudge when RISK-POLICY.md exists but the
|
|
5
|
+
# docs/risks/ standing-risk register directory is missing, is silent
|
|
6
|
+
# otherwise, and self-suppresses under the AFK guard
|
|
7
|
+
# (WR_SUPPRESS_OVERSIGHT_NUDGE=1 per ADR-068) so the interactive
|
|
8
|
+
# scaffold-confirm never fires into an absent-user iteration (JTBD-006).
|
|
9
|
+
# Behavioural — exercises the hook against fixture trees and asserts on stdout.
|
|
10
|
+
|
|
11
|
+
setup() {
|
|
12
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
13
|
+
HOOK="$REPO_ROOT/packages/risk-scorer/hooks/risk-scorer-scaffold-nudge.sh"
|
|
14
|
+
PLUGIN_ROOT="$REPO_ROOT/packages/risk-scorer"
|
|
15
|
+
DIR="$(mktemp -d)"
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
teardown() {
|
|
19
|
+
rm -rf "$DIR"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
@test "emits a scaffold nudge when RISK-POLICY.md exists and docs/risks/ is missing" {
|
|
23
|
+
printf 'placeholder policy\n' > "$DIR/RISK-POLICY.md"
|
|
24
|
+
run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
25
|
+
[ "$status" -eq 0 ]
|
|
26
|
+
[[ "$output" == *"RISK-POLICY.md present but docs/risks/ is missing"* ]]
|
|
27
|
+
[[ "$output" == *"/wr-risk-scorer:bootstrap-catalog"* ]]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@test "silent when RISK-POLICY.md exists and docs/risks/ also exists" {
|
|
31
|
+
printf 'placeholder policy\n' > "$DIR/RISK-POLICY.md"
|
|
32
|
+
mkdir -p "$DIR/docs/risks"
|
|
33
|
+
run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
34
|
+
[ "$status" -eq 0 ]
|
|
35
|
+
[ -z "$output" ]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@test "silent when RISK-POLICY.md is absent (no policy file = no register expectation)" {
|
|
39
|
+
run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
40
|
+
[ "$status" -eq 0 ]
|
|
41
|
+
[ -z "$output" ]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@test "silent when RISK-POLICY.md is absent even if docs/risks/ exists" {
|
|
45
|
+
mkdir -p "$DIR/docs/risks"
|
|
46
|
+
run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
47
|
+
[ "$status" -eq 0 ]
|
|
48
|
+
[ -z "$output" ]
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@test "AFK guard WR_SUPPRESS_OVERSIGHT_NUDGE=1 suppresses the nudge entirely" {
|
|
52
|
+
printf 'placeholder policy\n' > "$DIR/RISK-POLICY.md"
|
|
53
|
+
run env WR_SUPPRESS_OVERSIGHT_NUDGE=1 CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
[ -z "$output" ]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@test "guard value other than 1 does not suppress" {
|
|
59
|
+
printf 'placeholder policy\n' > "$DIR/RISK-POLICY.md"
|
|
60
|
+
run env WR_SUPPRESS_OVERSIGHT_NUDGE=0 CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
61
|
+
[[ "$output" == *"docs/risks/ is missing"* ]]
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@test "silent when CLAUDE_PROJECT_DIR points at a non-existent path" {
|
|
65
|
+
run env CLAUDE_PROJECT_DIR="$DIR/nonexistent" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
66
|
+
[ "$status" -eq 0 ]
|
|
67
|
+
[ -z "$output" ]
|
|
68
|
+
}
|
package/package.json
CHANGED