@windyroad/jtbd 0.5.2 → 0.6.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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "wr-jtbd",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "Jobs-to-be-done enforcement for Claude Code"
5
5
  }
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/ (or docs/JOBS_TO_BE_DONE.md) and reviews proposed changes
5
- against documented jobs, persona constraints, and screen mappings. Reports alignment
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
- # Supports both docs/jtbd/ directory (preferred) and docs/JOBS_TO_BE_DONE.md (legacy).
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 — prefer directory, fall back to single file
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
@@ -1,8 +1,11 @@
1
1
  #!/bin/bash
2
2
  # JTBD - UserPromptSubmit hook
3
- # Detects JTBD docs in the project and injects delegation instruction.
4
- # Supports both docs/jtbd/ directory (preferred) and docs/JOBS_TO_BE_DONE.md (legacy).
5
- # If neither exists, instructs Claude to create via the update-guide skill.
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/, docs/JOBS_TO_BE_DONE.md,
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 or docs/JOBS_TO_BE_DONE.md.
56
- Edits to project files will be blocked until a JTBD document exists.
57
- Run /wr-jtbd:update-guide to generate one.
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
- # Supports both docs/jtbd/ directory (preferred) and docs/JOBS_TO_BE_DONE.md (legacy).
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
- # Determine JTBD path — prefer directory, fall back to single file
19
- JTBD_PATH="docs/JOBS_TO_BE_DONE.md"
20
- if [ -d "docs/jtbd" ]; then
21
- JTBD_PATH="docs/jtbd"
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: exempts docs/JOBS_TO_BE_DONE.md (backward compat)" {
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" != *"BLOCKED"* ]]
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 JOBS_TO_BE_DONE.md missing (no UI files)" {
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 JOBS_TO_BE_DONE.md missing (with UI files)" {
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 instruction when JOBS_TO_BE_DONE.md exists" {
34
- mkdir -p docs
35
- echo "# Jobs" > docs/JOBS_TO_BE_DONE.md
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: injects enforcement when docs/jtbd/README.md exists" {
42
- mkdir -p docs/jtbd
43
- echo "# Index" > docs/jtbd/README.md
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" == *"MANDATORY JTBD CHECK"* ]]
51
+ [[ "$output" != *"MANDATORY JTBD CHECK"* ]]
52
+ [[ "$output" == *"wr-jtbd:update-guide"* ]]
47
53
  }
48
54
 
49
- @test "eval: prefers docs/jtbd/ over docs/JOBS_TO_BE_DONE.md when both exist" {
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/JOBS_TO_BE_DONE.md fallback (legacy) ---
73
+ # --- Path support: docs/jtbd/ is the sole canonical layout (ADR-008 Option 3, P019) ---
74
74
 
75
- @test "uses docs/JOBS_TO_BE_DONE.md when docs/jtbd does not exist" {
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
- [ -f "$MARKER" ]
83
- [ -f "$HASH_FILE" ]
84
- [ "$(cat "$HASH_FILE")" != "missing" ]
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 "prefers docs/jtbd over docs/JOBS_TO_BE_DONE.md when both exist" {
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/jtbd",
3
- "version": "0.5.2",
3
+ "version": "0.6.0",
4
4
  "description": "Jobs-to-be-done enforcement for UI changes",
5
5
  "bin": {
6
6
  "windyroad-jtbd": "./bin/install.mjs"
@@ -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, replace its content with a pointer:
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: