@windyroad/jtbd 0.5.2 → 0.6.0-preview.133
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/.claude-plugin/plugin.json +1 -1
- package/agents/agent.md +2 -3
- package/hooks/jtbd-enforce-edit.sh +7 -6
- package/hooks/jtbd-eval.sh +11 -30
- package/hooks/jtbd-mark-reviewed.sh +8 -5
- package/hooks/test/jtbd-enforce-scope.bats +8 -2
- package/hooks/test/jtbd-eval.bats +18 -11
- package/hooks/test/jtbd-mark-reviewed.bats +11 -14
- package/package.json +1 -1
- package/skills/update-guide/SKILL.md +19 -1
package/agents/agent.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent
|
|
3
3
|
description: Jobs To Be Done reviewer. Use before editing any project file.
|
|
4
|
-
Reads docs/jtbd/
|
|
5
|
-
|
|
6
|
-
or gaps.
|
|
4
|
+
Reads docs/jtbd/ and reviews proposed changes against documented jobs,
|
|
5
|
+
persona constraints, and screen mappings. Reports alignment or gaps.
|
|
7
6
|
tools:
|
|
8
7
|
- Read
|
|
9
8
|
- Glob
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# JTBD - PreToolUse enforcement hook
|
|
3
3
|
# BLOCKS Edit/Write to project files until jtbd-lead is consulted.
|
|
4
|
-
#
|
|
4
|
+
# Canonical layout is docs/jtbd/ only (ADR-008, Option 3 chosen 2026-04-20).
|
|
5
|
+
# Projects still on legacy single-file docs/JOBS_TO_BE_DONE.md must run
|
|
6
|
+
# /wr-jtbd:update-guide to migrate — the gate is inactive until the
|
|
7
|
+
# directory layout exists.
|
|
5
8
|
# Uses shared review-gate.sh for TTL, drift detection, and fail-closed.
|
|
6
9
|
|
|
7
10
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
@@ -77,18 +80,16 @@ case "$FILE_PATH" in
|
|
|
77
80
|
exit 0 ;;
|
|
78
81
|
*/docs/jtbd/*|docs/jtbd/*)
|
|
79
82
|
exit 0 ;;
|
|
80
|
-
*/docs/JOBS_TO_BE_DONE.md|docs/JOBS_TO_BE_DONE.md)
|
|
81
|
-
exit 0 ;;
|
|
82
83
|
*/docs/PRODUCT_DISCOVERY.md|docs/PRODUCT_DISCOVERY.md)
|
|
83
84
|
exit 0 ;;
|
|
84
85
|
esac
|
|
85
86
|
|
|
86
|
-
# Determine JTBD path —
|
|
87
|
+
# Determine JTBD path — canonical directory layout only (ADR-008 Option 3).
|
|
88
|
+
# Legacy docs/JOBS_TO_BE_DONE.md is NOT consulted at runtime; the gate is
|
|
89
|
+
# inactive on projects that have not run /wr-jtbd:update-guide.
|
|
87
90
|
JTBD_PATH=""
|
|
88
91
|
if [ -d "docs/jtbd" ]; then
|
|
89
92
|
JTBD_PATH="docs/jtbd"
|
|
90
|
-
elif [ -f "docs/JOBS_TO_BE_DONE.md" ]; then
|
|
91
|
-
JTBD_PATH="docs/JOBS_TO_BE_DONE.md"
|
|
92
93
|
fi
|
|
93
94
|
|
|
94
95
|
# If no JTBD docs exist, block and direct to create skill
|
package/hooks/jtbd-eval.sh
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# JTBD - UserPromptSubmit hook
|
|
3
|
-
# Detects
|
|
4
|
-
#
|
|
5
|
-
#
|
|
3
|
+
# Detects the docs/jtbd/ directory in the project and injects the
|
|
4
|
+
# delegation instruction. Canonical layout is docs/jtbd/ only
|
|
5
|
+
# (ADR-008, Option 3 chosen 2026-04-20). Legacy docs/JOBS_TO_BE_DONE.md
|
|
6
|
+
# is NOT consulted at runtime — projects still on that layout must run
|
|
7
|
+
# /wr-jtbd:update-guide to migrate. The update-guide skill is the sole
|
|
8
|
+
# component permitted to read the legacy file (for one-shot migration).
|
|
6
9
|
|
|
7
10
|
if [ -f "docs/jtbd/README.md" ]; then
|
|
8
11
|
cat <<'HOOK_OUTPUT'
|
|
@@ -24,36 +27,14 @@ REQUIRED ACTIONS:
|
|
|
24
27
|
SCOPE: All project files.
|
|
25
28
|
Does NOT apply to: CSS, images, fonts, lockfiles, changesets, memory files,
|
|
26
29
|
plan files, docs/problems/ (problem tickets), docs/BRIEFING.md,
|
|
27
|
-
RISK-POLICY.md, .risk-reports/, docs/jtbd/,
|
|
28
|
-
docs/PRODUCT_DISCOVERY.md, docs/VOICE-AND-TONE.md, docs/STYLE-GUIDE.md.
|
|
29
|
-
HOOK_OUTPUT
|
|
30
|
-
elif [ -f "docs/JOBS_TO_BE_DONE.md" ]; then
|
|
31
|
-
cat <<'HOOK_OUTPUT'
|
|
32
|
-
INSTRUCTION: MANDATORY JTBD CHECK. YOU MUST FOLLOW THIS.
|
|
33
|
-
DETECTED: docs/JOBS_TO_BE_DONE.md exists in this project.
|
|
34
|
-
|
|
35
|
-
This is a NON-OPTIONAL instruction. You MUST use the jtbd-lead agent
|
|
36
|
-
before editing any project file. This is proactive. Do not wait for the
|
|
37
|
-
user to ask.
|
|
38
|
-
|
|
39
|
-
REQUIRED ACTIONS:
|
|
40
|
-
1. Use the Agent tool to delegate to wr-jtbd:agent
|
|
41
|
-
(subagent_type: "wr-jtbd:agent")
|
|
42
|
-
2. The jtbd-lead will review proposed changes against docs/JOBS_TO_BE_DONE.md
|
|
43
|
-
and PRODUCT_DISCOVERY.md persona definitions
|
|
44
|
-
3. Do NOT write or edit project files without jtbd-lead review FIRST
|
|
45
|
-
4. Do NOT skip this step even if you think you can handle it yourself
|
|
46
|
-
|
|
47
|
-
SCOPE: All project files.
|
|
48
|
-
Does NOT apply to: CSS, images, fonts, lockfiles, changesets, memory files,
|
|
49
|
-
plan files, docs/problems/ (problem tickets), docs/BRIEFING.md,
|
|
50
|
-
RISK-POLICY.md, .risk-reports/, docs/jtbd/, docs/JOBS_TO_BE_DONE.md,
|
|
30
|
+
RISK-POLICY.md, .risk-reports/, docs/jtbd/,
|
|
51
31
|
docs/PRODUCT_DISCOVERY.md, docs/VOICE-AND-TONE.md, docs/STYLE-GUIDE.md.
|
|
52
32
|
HOOK_OUTPUT
|
|
53
33
|
else
|
|
54
34
|
cat <<'HOOK_OUTPUT'
|
|
55
|
-
NOTE: This project has no docs/jtbd/ directory
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
NOTE: This project has no docs/jtbd/ directory. Edits to project files
|
|
36
|
+
will be blocked until a JTBD document exists. Run /wr-jtbd:update-guide
|
|
37
|
+
to generate one. If the project has a legacy docs/JOBS_TO_BE_DONE.md,
|
|
38
|
+
update-guide will migrate it into the directory layout (ADR-008 Option 3).
|
|
58
39
|
HOOK_OUTPUT
|
|
59
40
|
fi
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# JTBD - PostToolUse hook for Agent tool
|
|
3
3
|
# Creates session markers when jtbd-lead has been consulted with PASS verdict.
|
|
4
|
-
#
|
|
4
|
+
# Canonical layout is docs/jtbd/ only (ADR-008, Option 3 chosen 2026-04-20).
|
|
5
|
+
# Legacy docs/JOBS_TO_BE_DONE.md is NOT consulted at runtime.
|
|
5
6
|
|
|
6
7
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
7
8
|
source "$SCRIPT_DIR/lib/review-gate.sh"
|
|
@@ -15,11 +16,13 @@ if [ -z "$SESSION_ID" ]; then
|
|
|
15
16
|
exit 0
|
|
16
17
|
fi
|
|
17
18
|
|
|
18
|
-
#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
# Canonical JTBD path — directory only (ADR-008 Option 3). If the
|
|
20
|
+
# directory doesn't exist the marker is not stored; the gate will
|
|
21
|
+
# surface a "run update-guide" recommendation on the next edit.
|
|
22
|
+
if [ ! -d "docs/jtbd" ]; then
|
|
23
|
+
exit 0
|
|
22
24
|
fi
|
|
25
|
+
JTBD_PATH="docs/jtbd"
|
|
23
26
|
|
|
24
27
|
case "$SUBAGENT" in
|
|
25
28
|
*jtbd-lead*|*wr-jtbd*)
|
|
@@ -117,10 +117,16 @@ assert_path_blocked() {
|
|
|
117
117
|
[[ "$output" != *"BLOCKED"* ]]
|
|
118
118
|
}
|
|
119
119
|
|
|
120
|
-
@test "functional:
|
|
120
|
+
@test "functional: docs/JOBS_TO_BE_DONE.md is NOT an exempt governance artefact (ADR-008 Option 3, P019)" {
|
|
121
|
+
# Legacy single-file path is no longer a recognised governance artefact.
|
|
122
|
+
# When docs/jtbd/ exists the gate should fire against edits to the
|
|
123
|
+
# legacy file (it is not exempt). When docs/jtbd/ does not exist the
|
|
124
|
+
# gate blocks with an update-guide suggestion (covered separately).
|
|
125
|
+
mkdir -p docs/jtbd
|
|
126
|
+
echo "# Index" > docs/jtbd/README.md
|
|
121
127
|
run run_hook_with_file "docs/JOBS_TO_BE_DONE.md"
|
|
122
128
|
[ "$status" -eq 0 ]
|
|
123
|
-
[[ "$output"
|
|
129
|
+
[[ "$output" == *"BLOCKED"* ]]
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
@test "functional: blocks src/index.ts when no JTBD docs exist" {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bats
|
|
2
2
|
|
|
3
|
-
# Tests for jtbd-eval.sh — verifies JTBD suggestion fires for any project
|
|
3
|
+
# Tests for jtbd-eval.sh — verifies JTBD suggestion fires for any project.
|
|
4
|
+
# Canonical layout is docs/jtbd/ only (ADR-008 Option 3 chosen 2026-04-20).
|
|
5
|
+
# Legacy docs/JOBS_TO_BE_DONE.md is NOT consulted at runtime (P019).
|
|
4
6
|
|
|
5
7
|
setup() {
|
|
6
8
|
SCRIPT_DIR="$(cd "$(dirname "$BATS_TEST_FILENAME")/.." && pwd)"
|
|
@@ -15,14 +17,14 @@ teardown() {
|
|
|
15
17
|
rm -rf "$TEST_DIR"
|
|
16
18
|
}
|
|
17
19
|
|
|
18
|
-
@test "eval: suggests update-guide when
|
|
20
|
+
@test "eval: suggests update-guide when docs/jtbd/ missing (no UI files)" {
|
|
19
21
|
# No UI files, no docs — should still suggest
|
|
20
22
|
run bash "$HOOK"
|
|
21
23
|
[ "$status" -eq 0 ]
|
|
22
24
|
[[ "$output" == *"wr-jtbd:update-guide"* ]]
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
@test "eval: suggests update-guide when
|
|
27
|
+
@test "eval: suggests update-guide when docs/jtbd/ missing (with UI files)" {
|
|
26
28
|
mkdir -p src
|
|
27
29
|
touch src/App.tsx
|
|
28
30
|
run bash "$HOOK"
|
|
@@ -30,29 +32,34 @@ teardown() {
|
|
|
30
32
|
[[ "$output" == *"wr-jtbd:update-guide"* ]]
|
|
31
33
|
}
|
|
32
34
|
|
|
33
|
-
@test "eval: injects enforcement
|
|
34
|
-
mkdir -p docs
|
|
35
|
-
echo "#
|
|
35
|
+
@test "eval: injects enforcement when docs/jtbd/README.md exists" {
|
|
36
|
+
mkdir -p docs/jtbd
|
|
37
|
+
echo "# Index" > docs/jtbd/README.md
|
|
36
38
|
run bash "$HOOK"
|
|
37
39
|
[ "$status" -eq 0 ]
|
|
38
40
|
[[ "$output" == *"MANDATORY JTBD CHECK"* ]]
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
@test "eval:
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
@test "eval: does NOT consult legacy docs/JOBS_TO_BE_DONE.md (ADR-008 Option 3, P019)" {
|
|
44
|
+
# Legacy single-file layout — gate must NOT inject the enforcement
|
|
45
|
+
# instruction; instead it should suggest update-guide so the project
|
|
46
|
+
# migrates into the directory layout.
|
|
47
|
+
mkdir -p docs
|
|
48
|
+
echo "# Jobs" > docs/JOBS_TO_BE_DONE.md
|
|
44
49
|
run bash "$HOOK"
|
|
45
50
|
[ "$status" -eq 0 ]
|
|
46
|
-
[[ "$output"
|
|
51
|
+
[[ "$output" != *"MANDATORY JTBD CHECK"* ]]
|
|
52
|
+
[[ "$output" == *"wr-jtbd:update-guide"* ]]
|
|
47
53
|
}
|
|
48
54
|
|
|
49
|
-
@test "eval:
|
|
55
|
+
@test "eval: uses docs/jtbd/ when both layouts coexist (ADR-008 Option 3)" {
|
|
50
56
|
mkdir -p docs/jtbd
|
|
51
57
|
echo "# Index" > docs/jtbd/README.md
|
|
52
58
|
echo "# Jobs" > docs/JOBS_TO_BE_DONE.md
|
|
53
59
|
run bash "$HOOK"
|
|
54
60
|
[ "$status" -eq 0 ]
|
|
55
61
|
[[ "$output" == *"docs/jtbd"* ]]
|
|
62
|
+
[[ "$output" == *"MANDATORY JTBD CHECK"* ]]
|
|
56
63
|
}
|
|
57
64
|
|
|
58
65
|
@test "eval: does not reference UI-only scoping in output" {
|
|
@@ -70,28 +70,24 @@ run_hook() {
|
|
|
70
70
|
[ "$HASH_README_ONLY" = "$HASH_README_CHANGED" ]
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
# --- Path support: docs/
|
|
73
|
+
# --- Path support: docs/jtbd/ is the sole canonical layout (ADR-008 Option 3, P019) ---
|
|
74
74
|
|
|
75
|
-
@test "
|
|
75
|
+
@test "does NOT store a review hash when only legacy docs/JOBS_TO_BE_DONE.md exists (P019)" {
|
|
76
|
+
# Legacy single-file layout — the mark-reviewed hook must exit early
|
|
77
|
+
# without storing a hash, because the enforce hook cannot gate the
|
|
78
|
+
# project until it runs /wr-jtbd:update-guide to migrate to docs/jtbd/.
|
|
76
79
|
mkdir -p docs
|
|
77
80
|
echo "# Jobs" > docs/JOBS_TO_BE_DONE.md
|
|
78
81
|
echo "PASS" > "$VERDICT_FILE"
|
|
79
82
|
|
|
80
83
|
run_hook "wr-jtbd:agent"
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
[ -f "$
|
|
84
|
-
[
|
|
85
|
-
|
|
86
|
-
# Hash should match the file's content hash. _hashcmd in
|
|
87
|
-
# gate-helpers.sh prefers md5sum, falls back to md5 -r, then shasum.
|
|
88
|
-
EXPECTED=$(cat docs/JOBS_TO_BE_DONE.md \
|
|
89
|
-
| (md5sum 2>/dev/null || md5 -r 2>/dev/null || shasum 2>/dev/null) \
|
|
90
|
-
| cut -d' ' -f1)
|
|
91
|
-
[ "$(cat "$HASH_FILE")" = "$EXPECTED" ]
|
|
85
|
+
# No marker, no hash file — the gate is inactive on legacy-layout projects.
|
|
86
|
+
[ ! -f "$MARKER" ]
|
|
87
|
+
[ ! -f "$HASH_FILE" ]
|
|
92
88
|
}
|
|
93
89
|
|
|
94
|
-
@test "
|
|
90
|
+
@test "hashes docs/jtbd/ when both layouts coexist (legacy single-file is ignored, P019)" {
|
|
95
91
|
mkdir -p docs/jtbd
|
|
96
92
|
echo "# job" > docs/jtbd/job.md
|
|
97
93
|
echo "# legacy jobs" > docs/JOBS_TO_BE_DONE.md
|
|
@@ -99,7 +95,8 @@ run_hook() {
|
|
|
99
95
|
|
|
100
96
|
run_hook "wr-jtbd:agent"
|
|
101
97
|
|
|
102
|
-
# The directory-derived hash must NOT equal the standalone-file hash
|
|
98
|
+
# The directory-derived hash must NOT equal the standalone-file hash —
|
|
99
|
+
# proves the hook did not consult the legacy file.
|
|
103
100
|
DIR_HASH="$(cat "$HASH_FILE")"
|
|
104
101
|
FILE_HASH=$(cat docs/JOBS_TO_BE_DONE.md \
|
|
105
102
|
| (md5sum 2>/dev/null || md5 -r 2>/dev/null || shasum 2>/dev/null) \
|
package/package.json
CHANGED
|
@@ -50,6 +50,14 @@ Check in order of preference:
|
|
|
50
50
|
If migrating from `docs/JOBS_TO_BE_DONE.md`, extract existing personas and jobs and
|
|
51
51
|
convert them into the directory structure. Ask the user before proceeding.
|
|
52
52
|
|
|
53
|
+
**Migration carve-out (ADR-008 Option 3 chosen 2026-04-20, P019)**: this skill is the
|
|
54
|
+
**sole component** in the plugin suite permitted to read `docs/JOBS_TO_BE_DONE.md`.
|
|
55
|
+
Every other component (eval hook, enforce hook, mark-reviewed hook, wr-jtbd:agent,
|
|
56
|
+
CI validation) reads only `docs/jtbd/`. Do NOT strip this read path from this skill
|
|
57
|
+
during future cleanup — it is the one-shot migration bridge for legacy projects. The
|
|
58
|
+
Reassessment Criteria in ADR-008 list the sunset trigger (no legacy-layout projects
|
|
59
|
+
remaining).
|
|
60
|
+
|
|
53
61
|
### 3. Draft personas
|
|
54
62
|
|
|
55
63
|
For each persona (2-4), create a file at `docs/jtbd/<persona-name>/persona.md`:
|
|
@@ -155,7 +163,10 @@ Write `docs/jtbd/README.md` with tables grouping jobs by persona and status:
|
|
|
155
163
|
|
|
156
164
|
### 8. Handle legacy file
|
|
157
165
|
|
|
158
|
-
If `docs/JOBS_TO_BE_DONE.md` exists,
|
|
166
|
+
If `docs/JOBS_TO_BE_DONE.md` exists, after successfully migrating its content
|
|
167
|
+
into the directory layout, recommend deleting it (git history is the archive,
|
|
168
|
+
per ADR-008 Option 3 Consequences). If the user prefers to keep a stub for
|
|
169
|
+
external links, offer to replace its content with a pointer:
|
|
159
170
|
|
|
160
171
|
```markdown
|
|
161
172
|
# Jobs To Be Done
|
|
@@ -163,8 +174,15 @@ If `docs/JOBS_TO_BE_DONE.md` exists, replace its content with a pointer:
|
|
|
163
174
|
Job definitions have been migrated to individual files in `docs/jtbd/`.
|
|
164
175
|
Each persona has its own directory with a persona definition and individual
|
|
165
176
|
job files. See `docs/jtbd/README.md` for the full index.
|
|
177
|
+
|
|
178
|
+
This file is no longer consulted by the `@windyroad/jtbd` plugin at runtime
|
|
179
|
+
(ADR-008 Option 3). It is retained only for external links.
|
|
166
180
|
```
|
|
167
181
|
|
|
182
|
+
Default recommendation: delete the file once migration is confirmed. The
|
|
183
|
+
repository's own `docs/JOBS_TO_BE_DONE.md` stub was deleted in the same
|
|
184
|
+
commit that accepted ADR-008 Option 3 (P019).
|
|
185
|
+
|
|
168
186
|
### 9. Summary
|
|
169
187
|
|
|
170
188
|
Report what was created:
|