@windyroad/jtbd 0.12.0 → 0.12.1-preview.563
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.
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
11
|
source "$SCRIPT_DIR/lib/review-gate.sh"
|
|
12
12
|
|
|
13
|
+
# P191: resolve the project root from the session signal, not the hook's
|
|
14
|
+
# runtime CWD. Claude Code may launch the hook with an actual working
|
|
15
|
+
# directory that differs from the session/project dir while still exporting
|
|
16
|
+
# CLAUDE_PROJECT_DIR (and a $PWD env var) pointing at the project. A relative
|
|
17
|
+
# `[ -d "docs/jtbd" ]` then false-negatives even though docs/jtbd is present,
|
|
18
|
+
# tripping the fail-closed "no JTBD documentation" deny on legitimate edits.
|
|
19
|
+
# Anchor every project-relative check on PROJECT_DIR. Pattern mirrors
|
|
20
|
+
# jtbd-oversight-nudge.sh.
|
|
21
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
22
|
+
|
|
13
23
|
INPUT=$(cat)
|
|
14
24
|
|
|
15
25
|
FILE_PATH=$(echo "$INPUT" | python3 -c "
|
|
@@ -44,7 +54,7 @@ fi
|
|
|
44
54
|
case "$FILE_PATH" in
|
|
45
55
|
/*)
|
|
46
56
|
case "$FILE_PATH" in
|
|
47
|
-
"$
|
|
57
|
+
"$PROJECT_DIR"/*) ;;
|
|
48
58
|
*) exit 0 ;;
|
|
49
59
|
esac
|
|
50
60
|
;;
|
|
@@ -107,8 +117,8 @@ esac
|
|
|
107
117
|
# Legacy docs/JOBS_TO_BE_DONE.md is NOT consulted at runtime; the gate is
|
|
108
118
|
# inactive on projects that have not run /wr-jtbd:update-guide.
|
|
109
119
|
JTBD_PATH=""
|
|
110
|
-
if [ -d "docs/jtbd" ]; then
|
|
111
|
-
JTBD_PATH="docs/jtbd"
|
|
120
|
+
if [ -d "$PROJECT_DIR/docs/jtbd" ]; then
|
|
121
|
+
JTBD_PATH="$PROJECT_DIR/docs/jtbd"
|
|
112
122
|
fi
|
|
113
123
|
|
|
114
124
|
# If no JTBD docs exist, block and direct to create skill
|
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
8
|
source "$SCRIPT_DIR/lib/review-gate.sh"
|
|
9
9
|
|
|
10
|
+
# P191: anchor the docs/jtbd detection on the project root, not the hook's
|
|
11
|
+
# runtime CWD (see jtbd-enforce-edit.sh for the full rationale). If this
|
|
12
|
+
# marker-write side false-negatives on docs/jtbd it never stores the marker,
|
|
13
|
+
# and the enforce gate then denies the next edit for lack of a marker.
|
|
14
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$PWD}"
|
|
15
|
+
|
|
10
16
|
INPUT=$(cat)
|
|
11
17
|
|
|
12
18
|
SUBAGENT=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // empty') || true
|
|
@@ -19,10 +25,10 @@ fi
|
|
|
19
25
|
# Canonical JTBD path — directory only (ADR-008 Option 3). If the
|
|
20
26
|
# directory doesn't exist the marker is not stored; the gate will
|
|
21
27
|
# surface a "run update-guide" recommendation on the next edit.
|
|
22
|
-
if [ ! -d "docs/jtbd" ]; then
|
|
28
|
+
if [ ! -d "$PROJECT_DIR/docs/jtbd" ]; then
|
|
23
29
|
exit 0
|
|
24
30
|
fi
|
|
25
|
-
JTBD_PATH="docs/jtbd"
|
|
31
|
+
JTBD_PATH="$PROJECT_DIR/docs/jtbd"
|
|
26
32
|
|
|
27
33
|
case "$SUBAGENT" in
|
|
28
34
|
*jtbd-lead*|*wr-jtbd*)
|
|
@@ -24,3 +24,37 @@ run_hook_with_file() {
|
|
|
24
24
|
[ "$status" -eq 0 ]
|
|
25
25
|
[[ "$output" != *"BLOCKED"* ]]
|
|
26
26
|
}
|
|
27
|
+
|
|
28
|
+
# P191: the gate must resolve docs/jtbd from the project root
|
|
29
|
+
# (CLAUDE_PROJECT_DIR), NOT the hook's actual runtime CWD. Claude Code can
|
|
30
|
+
# launch the hook with a working directory that differs from the session/
|
|
31
|
+
# project dir; a relative `[ -d "docs/jtbd" ]` then false-negatives and the
|
|
32
|
+
# fail-closed "no JTBD documentation" branch blocks legitimate edits even
|
|
33
|
+
# though docs/jtbd is present.
|
|
34
|
+
@test "jtbd project-root: detects docs/jtbd via CLAUDE_PROJECT_DIR when hook CWD differs (P191)" {
|
|
35
|
+
local proj other json
|
|
36
|
+
proj="$(mktemp -d)"
|
|
37
|
+
other="$(mktemp -d)" # a CWD that does NOT contain docs/jtbd
|
|
38
|
+
mkdir -p "$proj/docs/jtbd"
|
|
39
|
+
echo "# job" > "$proj/docs/jtbd/JTBD-001-x.md"
|
|
40
|
+
json="{\"tool_input\":{\"file_path\":\"${proj}/packages/x/foo.sh\"},\"session_id\":\"test-$$\"}"
|
|
41
|
+
# Fire the hook from `other` (wrong CWD) but with CLAUDE_PROJECT_DIR set to
|
|
42
|
+
# the real project. Pre-fix this emitted "no JTBD documentation exists";
|
|
43
|
+
# post-fix the gate is ACTIVE and denies for the missing review marker.
|
|
44
|
+
run env CLAUDE_PROJECT_DIR="$proj" bash -c "cd '$other' && printf '%s' '$json' | bash '$HOOK'"
|
|
45
|
+
rm -rf "$proj" "$other"
|
|
46
|
+
[[ "$output" != *"no JTBD documentation exists"* ]]
|
|
47
|
+
[[ "$output" == *"without JTBD review"* ]]
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# P191 regression guard: when docs/jtbd genuinely does not exist under the
|
|
51
|
+
# project root, the fail-closed "no JTBD documentation" deny is preserved
|
|
52
|
+
# (the fix narrows the false-negative; it must not silence true-absence).
|
|
53
|
+
@test "jtbd project-root: genuinely-absent docs/jtbd still denies (fail-closed preserved, P191)" {
|
|
54
|
+
local proj json
|
|
55
|
+
proj="$(mktemp -d)" # no docs/jtbd created
|
|
56
|
+
json="{\"tool_input\":{\"file_path\":\"${proj}/foo.sh\"},\"session_id\":\"test-$$\"}"
|
|
57
|
+
run env CLAUDE_PROJECT_DIR="$proj" bash -c "printf '%s' '$json' | bash '$HOOK'"
|
|
58
|
+
rm -rf "$proj"
|
|
59
|
+
[[ "$output" == *"no JTBD documentation exists"* ]]
|
|
60
|
+
}
|