@windyroad/jtbd 0.8.3-preview.374 → 0.8.3-preview.387
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/README.md +9 -16
- package/bin/wr-jtbd-detect-unoversighted +3 -0
- package/hooks/hooks.json +3 -0
- package/hooks/jtbd-oversight-nudge.sh +42 -0
- package/hooks/test/jtbd-oversight-nudge.bats +69 -0
- package/package.json +2 -1
- package/scripts/detect-unoversighted.sh +47 -0
- package/scripts/test/detect-unoversighted.bats +85 -0
- package/skills/confirm-jobs-and-personas/SKILL.md +74 -0
- package/skills/update-guide/SKILL.md +18 -0
package/README.md
CHANGED
|
@@ -33,6 +33,14 @@ The plugin works automatically. On first use in a project without a JTBD directo
|
|
|
33
33
|
|
|
34
34
|
This examines your existing features and asks about your user jobs, personas, and desired outcomes to generate `docs/jtbd/<persona>/persona.md` plus per-job files at `docs/jtbd/<persona>/JTBD-NNN-<title>.<status>.md`. If a legacy `docs/JOBS_TO_BE_DONE.md` exists, it is migrated into the directory structure on first run (per [ADR-008](../../docs/decisions/008-jtbd-directory-structure.proposed.md)).
|
|
35
35
|
|
|
36
|
+
**Confirm jobs and personas that lack human oversight:**
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
/wr-jtbd:confirm-jobs-and-personas
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The `confirm-jobs-and-personas` skill drains the set of jobs/personas that were recorded without a human confirming they reflect real user/business need (per [ADR-068](../../docs/decisions/068-jtbd-persona-human-oversight-marker-and-confirm-drain.proposed.md)). It surfaces each via AskUserQuestion so you confirm, amend, or reject it, then writes a `human-oversight: confirmed` marker. Detection is a token-cheap grep over `docs/jtbd/` frontmatter; a session-start nudge reports the unoversighted count. Jobs/personas created through `update-guide` are born oversighted, so the unconfirmed set only shrinks. This is the read-write oversight drain — distinct from the read-only `/wr-jtbd:review-jobs` alignment reviewer.
|
|
43
|
+
|
|
36
44
|
## How It Works
|
|
37
45
|
|
|
38
46
|
| Hook | Trigger | What it does |
|
|
@@ -41,6 +49,7 @@ This examines your existing features and asks about your user jobs, personas, an
|
|
|
41
49
|
| `jtbd-enforce-edit.sh` | Edit or Write | Blocks edits until the JTBD agent has reviewed |
|
|
42
50
|
| `jtbd-mark-reviewed.sh` | Agent completes | Marks the review as done (TTL: 3600s) |
|
|
43
51
|
| `jtbd-slide-marker.sh` | Agent or Bash | Slides the review marker forward across non-edit operations so an active review session is not invalidated by intervening Bash or sub-agent calls |
|
|
52
|
+
| `jtbd-oversight-nudge.sh` | Session start | Reports how many jobs/personas lack human oversight and points to `/wr-jtbd:confirm-jobs-and-personas`; silent when none, and self-suppressed inside AFK iterations |
|
|
44
53
|
|
|
45
54
|
## Agent
|
|
46
55
|
|
|
@@ -50,22 +59,6 @@ The `wr-jtbd:agent` reads your `docs/jtbd/` directory and reviews proposed UI ch
|
|
|
50
59
|
- Persona definitions and constraints
|
|
51
60
|
- Screen-to-job mappings
|
|
52
61
|
|
|
53
|
-
## Jobs to be Done
|
|
54
|
-
|
|
55
|
-
This plugin serves the [Jobs to be Done](../../docs/jtbd/) below. Per [ADR-051](../../docs/decisions/051-jtbd-anchored-readme-with-drift-advisory.proposed.md), the persona-grouped JTBD anchor is the canonical source of truth for the README's value framing.
|
|
56
|
-
|
|
57
|
-
### Solo developer
|
|
58
|
-
|
|
59
|
-
- **[JTBD-001 Enforce Governance Without Slowing Down](../../docs/jtbd/solo-developer/JTBD-001-enforce-governance.proposed.md)** — JTBD review fires automatically on every UI edit; manual review is replaced by an agent reading the persona files the project already maintains.
|
|
60
|
-
|
|
61
|
-
### Tech lead / consultant
|
|
62
|
-
|
|
63
|
-
- **[JTBD-202 Run Pre-Flight Governance Checks Before Release or Handover](../../docs/jtbd/tech-lead/JTBD-202-pre-flight-governance-check.proposed.md)** — `/wr-jtbd:review-jobs` produces an on-demand alignment report against documented jobs, attachable to a release note or handover doc.
|
|
64
|
-
|
|
65
|
-
### Plugin user
|
|
66
|
-
|
|
67
|
-
- **[JTBD-302 Trust That the README Describes the Plugin I Just Installed](../../docs/jtbd/plugin-user/JTBD-302-trust-readme-describes-installed-behaviour.proposed.md)** — this README is anchored on current JTBD job IDs; drift between prose and shipped behaviour is detectable at retro time per ADR-051.
|
|
68
|
-
|
|
69
62
|
## Updating and Uninstalling
|
|
70
63
|
|
|
71
64
|
```bash
|
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/jtbd-oversight-nudge.sh" }] }
|
|
5
|
+
],
|
|
3
6
|
"UserPromptSubmit": [
|
|
4
7
|
{ "hooks": [{ "type": "command", "command": "${CLAUDE_PLUGIN_ROOT}/hooks/jtbd-eval.sh" }] }
|
|
5
8
|
],
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# wr-jtbd — SessionStart hook (ADR-068)
|
|
3
|
+
#
|
|
4
|
+
# Surfaces a one-line nudge when jobs/personas lack the human-oversight marker,
|
|
5
|
+
# so the user can drain them via /wr-jtbd:confirm-jobs-and-personas. Sibling of
|
|
6
|
+
# packages/architect/hooks/architect-oversight-nudge.sh (ADR-066); same shape as
|
|
7
|
+
# the ADR-040 session-start surface.
|
|
8
|
+
#
|
|
9
|
+
# Detection is token-cheap: delegates to detect-unoversighted.sh (a grep over
|
|
10
|
+
# docs/jtbd/ frontmatter — no body reads, no per-file LLM call). Silent when the
|
|
11
|
+
# unoversighted count is zero (steady state once the set is drained).
|
|
12
|
+
#
|
|
13
|
+
# AFK self-suppress: shares the suite-wide WR_SUPPRESS_OVERSIGHT_NUDGE guard with
|
|
14
|
+
# the architect oversight nudge (ADR-068 § shared cross-plugin contracts). AFK
|
|
15
|
+
# orchestrators export it once (work-problems Step 5) and every oversight nudge
|
|
16
|
+
# self-suppresses — so this interactive batch-confirm nudge never fires into an
|
|
17
|
+
# absent-user subprocess (JTBD-006 friction guard). Only the literal "1" suppresses.
|
|
18
|
+
|
|
19
|
+
set -euo pipefail
|
|
20
|
+
|
|
21
|
+
if [ "${WR_SUPPRESS_OVERSIGHT_NUDGE:-}" = "1" ]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-.}"
|
|
26
|
+
JTBD_DIR="$PROJECT_DIR/docs/jtbd"
|
|
27
|
+
|
|
28
|
+
[ -d "$JTBD_DIR" ] || exit 0
|
|
29
|
+
|
|
30
|
+
DETECT="${CLAUDE_PLUGIN_ROOT:-$(dirname "$0")/..}/scripts/detect-unoversighted.sh"
|
|
31
|
+
[ -x "$DETECT" ] || DETECT="$(dirname "$0")/../scripts/detect-unoversighted.sh"
|
|
32
|
+
|
|
33
|
+
COUNT="$(bash "$DETECT" "$JTBD_DIR" 2>/dev/null | grep -c . || true)"
|
|
34
|
+
COUNT="${COUNT:-0}"
|
|
35
|
+
|
|
36
|
+
[ "$COUNT" -gt 0 ] 2>/dev/null || exit 0
|
|
37
|
+
|
|
38
|
+
if [ "$COUNT" -eq 1 ]; then
|
|
39
|
+
echo "[wr-jtbd] 1 job/persona lacks human oversight — run /wr-jtbd:confirm-jobs-and-personas to confirm it."
|
|
40
|
+
else
|
|
41
|
+
echo "[wr-jtbd] $COUNT jobs/personas lack human oversight — run /wr-jtbd:confirm-jobs-and-personas to confirm them."
|
|
42
|
+
fi
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# ADR-068: jtbd-oversight-nudge.sh (SessionStart) emits a one-line nudge when
|
|
4
|
+
# jobs/personas lack the human-oversight marker, is silent when none do, and
|
|
5
|
+
# self-suppresses under the shared AFK guard (WR_SUPPRESS_OVERSIGHT_NUDGE=1).
|
|
6
|
+
# Behavioural — exercises the hook against fixture docs/jtbd/ trees.
|
|
7
|
+
|
|
8
|
+
setup() {
|
|
9
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
10
|
+
HOOK="$REPO_ROOT/packages/jtbd/hooks/jtbd-oversight-nudge.sh"
|
|
11
|
+
PLUGIN_ROOT="$REPO_ROOT/packages/jtbd"
|
|
12
|
+
DIR="$(mktemp -d)"
|
|
13
|
+
mkdir -p "$DIR/docs/jtbd/solo-developer"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
teardown() { rm -rf "$DIR"; }
|
|
17
|
+
|
|
18
|
+
mk_unmarked() {
|
|
19
|
+
mkdir -p "$(dirname "$DIR/docs/jtbd/$1")"
|
|
20
|
+
{ echo "---"; echo "status: proposed"; echo "date-created: 2026-05-25"; echo "---"; echo "# $1"; } \
|
|
21
|
+
> "$DIR/docs/jtbd/$1"
|
|
22
|
+
}
|
|
23
|
+
mk_marked() {
|
|
24
|
+
mkdir -p "$(dirname "$DIR/docs/jtbd/$1")"
|
|
25
|
+
{ echo "---"; echo "status: proposed"; echo "human-oversight: confirmed"; echo "---"; echo "# $1"; } \
|
|
26
|
+
> "$DIR/docs/jtbd/$1"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@test "emits a count line when there are unoversighted jobs/personas" {
|
|
30
|
+
mk_unmarked "solo-developer/persona.md"
|
|
31
|
+
mk_unmarked "solo-developer/JTBD-001-foo.proposed.md"
|
|
32
|
+
run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
33
|
+
[ "$status" -eq 0 ]
|
|
34
|
+
[[ "$output" == *"2 jobs/personas lack human oversight"* ]]
|
|
35
|
+
[[ "$output" == *"/wr-jtbd:confirm-jobs-and-personas"* ]]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@test "uses singular wording for exactly one unoversighted artifact" {
|
|
39
|
+
mk_unmarked "solo-developer/persona.md"
|
|
40
|
+
run env CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
41
|
+
[[ "$output" == *"1 job/persona lacks human oversight"* ]]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@test "silent when every job/persona is confirmed" {
|
|
45
|
+
mk_marked "solo-developer/persona.md"
|
|
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 "shared AFK guard suppresses the nudge entirely" {
|
|
52
|
+
mk_unmarked "solo-developer/persona.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
|
+
mk_unmarked "solo-developer/persona.md"
|
|
60
|
+
mk_unmarked "solo-developer/JTBD-001-foo.proposed.md"
|
|
61
|
+
run env WR_SUPPRESS_OVERSIGHT_NUDGE=0 CLAUDE_PROJECT_DIR="$DIR" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
62
|
+
[[ "$output" == *"lack human oversight"* ]]
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@test "silent when project has no docs/jtbd dir" {
|
|
66
|
+
run env CLAUDE_PROJECT_DIR="$DIR/empty" CLAUDE_PLUGIN_ROOT="$PLUGIN_ROOT" bash "$HOOK"
|
|
67
|
+
[ "$status" -eq 0 ]
|
|
68
|
+
[ -z "$output" ]
|
|
69
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@windyroad/jtbd",
|
|
3
|
-
"version": "0.8.3-preview.
|
|
3
|
+
"version": "0.8.3-preview.387",
|
|
4
4
|
"description": "Jobs-to-be-done enforcement for UI changes",
|
|
5
5
|
"bin": {
|
|
6
6
|
"windyroad-jtbd": "./bin/install.mjs"
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"agents/",
|
|
24
24
|
"hooks/",
|
|
25
25
|
"skills/",
|
|
26
|
+
"scripts/",
|
|
26
27
|
".claude-plugin/",
|
|
27
28
|
"lib/"
|
|
28
29
|
]
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# wr-jtbd — detect jobs/personas lacking the human-oversight marker (ADR-068)
|
|
3
|
+
#
|
|
4
|
+
# @jtbd JTBD-202 (Run Pre-Flight Governance Checks — oversight state of the JTBD corpus)
|
|
5
|
+
# @jtbd JTBD-101 (Extend the Suite with New Plugins — reusable adopter-portable primitive)
|
|
6
|
+
#
|
|
7
|
+
# Sibling of packages/architect/scripts/detect-unoversighted.sh (ADR-066). Token-cheap:
|
|
8
|
+
# greps each job/persona's YAML frontmatter for `human-oversight: confirmed`. No body
|
|
9
|
+
# reads, no per-file LLM call. A file is "unoversighted" when its frontmatter does not
|
|
10
|
+
# carry that marker (or has no frontmatter).
|
|
11
|
+
#
|
|
12
|
+
# Usage:
|
|
13
|
+
# detect-unoversighted.sh [JTBD_DIR]
|
|
14
|
+
# JTBD_DIR defaults to docs/jtbd
|
|
15
|
+
#
|
|
16
|
+
# Output: one unoversighted job/persona file path per line, sorted. Empty output = the
|
|
17
|
+
# whole set is confirmed. Always exits 0 (it is a detector, not a gate).
|
|
18
|
+
#
|
|
19
|
+
# Consumed by: jtbd-oversight-nudge.sh (SessionStart count) and
|
|
20
|
+
# /wr-jtbd:confirm-jobs-and-personas (the drain list). Marker contract: ADR-068 (= ADR-066 field).
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
JTBD_DIR="${1:-docs/jtbd}"
|
|
25
|
+
[ -d "$JTBD_DIR" ] || exit 0
|
|
26
|
+
|
|
27
|
+
# JTBD layout (ADR-008): docs/jtbd/<persona>/persona.md + docs/jtbd/<persona>/JTBD-NNN-*.md,
|
|
28
|
+
# with docs/jtbd/README.md as the top-level index. Match the per-persona files; README is
|
|
29
|
+
# never a job/persona record.
|
|
30
|
+
shopt -s nullglob
|
|
31
|
+
for f in "$JTBD_DIR"/*/*.md "$JTBD_DIR"/*.md; do
|
|
32
|
+
base="$(basename "$f")"
|
|
33
|
+
[ "$base" = "README.md" ] && continue
|
|
34
|
+
# Superseded artifacts (if an adopter uses a .superseded.md suffix) are retired.
|
|
35
|
+
case "$base" in *.superseded.md) continue ;; esac
|
|
36
|
+
|
|
37
|
+
fm="$(awk '
|
|
38
|
+
NR==1 && $0 != "---" { exit }
|
|
39
|
+
NR==1 { next }
|
|
40
|
+
/^---[[:space:]]*$/ { exit }
|
|
41
|
+
{ print }
|
|
42
|
+
' "$f")"
|
|
43
|
+
|
|
44
|
+
if ! printf '%s\n' "$fm" | grep -qiE '^human-oversight:[[:space:]]*confirmed[[:space:]]*$'; then
|
|
45
|
+
echo "$f"
|
|
46
|
+
fi
|
|
47
|
+
done | sort
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
|
|
3
|
+
# ADR-068: detect-unoversighted.sh prints jobs/personas whose frontmatter lacks the
|
|
4
|
+
# `human-oversight: confirmed` marker. Behavioural — exercises the script against
|
|
5
|
+
# fixture docs/jtbd/<persona>/ trees and asserts on stdout.
|
|
6
|
+
|
|
7
|
+
setup() {
|
|
8
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
9
|
+
SCRIPT="$REPO_ROOT/packages/jtbd/scripts/detect-unoversighted.sh"
|
|
10
|
+
DIR="$(mktemp -d)"
|
|
11
|
+
mkdir -p "$DIR/docs/jtbd/solo-developer"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
teardown() { rm -rf "$DIR"; }
|
|
15
|
+
|
|
16
|
+
mk() { # mk <relpath under docs/jtbd> <extra frontmatter lines...>
|
|
17
|
+
local rel="$1"; shift
|
|
18
|
+
mkdir -p "$(dirname "$DIR/docs/jtbd/$rel")"
|
|
19
|
+
{
|
|
20
|
+
echo "---"
|
|
21
|
+
echo "status: proposed"
|
|
22
|
+
echo "date-created: 2026-05-25"
|
|
23
|
+
for line in "$@"; do echo "$line"; done
|
|
24
|
+
echo "---"
|
|
25
|
+
echo "# $rel"
|
|
26
|
+
} > "$DIR/docs/jtbd/$rel"
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@test "a job without the marker is reported" {
|
|
30
|
+
mk "solo-developer/JTBD-001-foo.proposed.md"
|
|
31
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
32
|
+
[ "$status" -eq 0 ]
|
|
33
|
+
[[ "$output" == *"JTBD-001-foo.proposed.md"* ]]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@test "a persona file without the marker is reported" {
|
|
37
|
+
mk "solo-developer/persona.md"
|
|
38
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
39
|
+
[[ "$output" == *"solo-developer/persona.md"* ]]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@test "a job carrying human-oversight: confirmed is NOT reported" {
|
|
43
|
+
mk "solo-developer/JTBD-002-bar.proposed.md" "human-oversight: confirmed" "oversight-date: 2026-05-25"
|
|
44
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
45
|
+
[[ "$output" != *"JTBD-002-bar.proposed.md"* ]]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@test "the top-level docs/jtbd/README.md is never reported" {
|
|
49
|
+
echo "# JTBD index" > "$DIR/docs/jtbd/README.md"
|
|
50
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
51
|
+
[[ "$output" != *"README.md"* ]]
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@test "a per-persona README is also excluded" {
|
|
55
|
+
echo "# persona index" > "$DIR/docs/jtbd/solo-developer/README.md"
|
|
56
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
57
|
+
[[ "$output" != *"README.md"* ]]
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@test "a file with no frontmatter counts as unoversighted" {
|
|
61
|
+
mkdir -p "$DIR/docs/jtbd/tech-lead"
|
|
62
|
+
echo "# bare persona, no frontmatter" > "$DIR/docs/jtbd/tech-lead/persona.md"
|
|
63
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
64
|
+
[[ "$output" == *"tech-lead/persona.md"* ]]
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@test "marker match is case-insensitive and tolerant of trailing space" {
|
|
68
|
+
mk "solo-developer/JTBD-003-baz.proposed.md" "human-oversight: confirmed "
|
|
69
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
70
|
+
[[ "$output" != *"JTBD-003-baz.proposed.md"* ]]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@test "missing jtbd dir exits 0 with no output" {
|
|
74
|
+
run bash "$SCRIPT" "$DIR/docs/nonexistent"
|
|
75
|
+
[ "$status" -eq 0 ]
|
|
76
|
+
[ -z "$output" ]
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@test "fully-confirmed corpus produces empty output" {
|
|
80
|
+
mk "solo-developer/persona.md" "human-oversight: confirmed"
|
|
81
|
+
mk "solo-developer/JTBD-001-foo.proposed.md" "human-oversight: confirmed"
|
|
82
|
+
run bash "$SCRIPT" "$DIR/docs/jtbd"
|
|
83
|
+
[ "$status" -eq 0 ]
|
|
84
|
+
[ -z "$output" ]
|
|
85
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wr-jtbd:confirm-jobs-and-personas
|
|
3
|
+
description: Drain the set of Jobs To Be Done and personas that lack human oversight. Surfaces each auto-derived job/persona via AskUserQuestion so a human confirms, amends, or rejects it, then writes the human-oversight marker. Use when the session-start nudge reports jobs/personas lack oversight, or any time you want to review the documented JTBD corpus. This is the read-write oversight drain — distinct from /wr-jtbd:review-jobs (the read-only alignment reviewer).
|
|
4
|
+
allowed-tools: Read, Glob, Grep, Bash, Edit, AskUserQuestion
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Confirm Jobs and Personas — human-oversight drain
|
|
8
|
+
|
|
9
|
+
Lift auto-derived Jobs To Be Done and personas to human decisions. Documented jobs/personas are load-bearing: the JTBD edit gate reviews every project change against `docs/jtbd/`, so a job or persona that was agent-derived without a human confirming it reflects real need propagates wrong alignment verdicts. This skill drains the **unoversighted set** (jobs/personas lacking `human-oversight: confirmed`, per ADR-068): it surfaces each via `AskUserQuestion`, and writes the oversight marker only when a human confirms.
|
|
10
|
+
|
|
11
|
+
This is the P288 / ADR-068 drain surface — the JTBD sibling of `/wr-architect:review-decisions`. It is **read-write** (writes the marker on confirm). It is NOT the same as `/wr-jtbd:review-jobs`, which is a read-only alignment review ("do my changes trace to documented jobs?"); this skill confirms the jobs/personas themselves.
|
|
12
|
+
|
|
13
|
+
## When to use
|
|
14
|
+
|
|
15
|
+
- The session-start nudge reported `N jobs/personas lack human oversight`.
|
|
16
|
+
- Pre-handover / pre-release: confirm the JTBD corpus reflects real user/business need.
|
|
17
|
+
- After an `update-guide` run or agent-derived job/persona authoring landed files without confirmation.
|
|
18
|
+
- Any focused sitting — designed for **batches over multiple sittings**, not one blocking pass.
|
|
19
|
+
|
|
20
|
+
## How it works
|
|
21
|
+
|
|
22
|
+
The marker persists (ADR-009 never-re-ask principle), so a partially-drained set resumes cleanly on the next run.
|
|
23
|
+
|
|
24
|
+
### Step 1: Enumerate the unoversighted set
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
wr-jtbd-detect-unoversighted docs/jtbd
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The `wr-jtbd-detect-unoversighted` command is a `$PATH`-resolved shim (ADR-049) dispatching `packages/jtbd/scripts/detect-unoversighted.sh`. It prints one unoversighted job/persona path per line (README excluded; token-cheap grep over frontmatter — no body reads). Empty output → the corpus is fully confirmed; report and stop.
|
|
31
|
+
|
|
32
|
+
### Step 2: Cluster + order
|
|
33
|
+
|
|
34
|
+
Read **only the frontmatter + title + Job Statement / persona "Who" section** of each unoversighted file (not full bodies — keep it cheap). Group by persona directory and order **load-bearing first**: personas before their jobs (a persona frames its jobs), and jobs that other artifacts (problems, RFCs, READMEs) cite most heavily before narrow ones.
|
|
35
|
+
|
|
36
|
+
### Step 3: Present each via AskUserQuestion (batched)
|
|
37
|
+
|
|
38
|
+
For each job/persona in the ordered queue, surface it as an `AskUserQuestion` (cap **4 per call** per ADR-013 Rule 1; issue further calls sequentially):
|
|
39
|
+
|
|
40
|
+
- **Question**: the job statement (for a JTBD) or the persona definition (who they are + key constraints), in one line.
|
|
41
|
+
- **Context**: grounded in what the file actually says (per ADR-026) — the persona served, the desired outcomes, any cited problems/RFCs.
|
|
42
|
+
- **Options** per artifact:
|
|
43
|
+
- **Confirm** — the job/persona accurately reflects real need; write the marker.
|
|
44
|
+
- **Amend** — mostly right but needs a change; capture it, apply it to the file, then write the marker.
|
|
45
|
+
- **Reject** — the auto-derived job/persona does not reflect real need; do NOT write the marker. Note the rework (a `wr-jtbd:update-guide` rewrite, or retirement).
|
|
46
|
+
- **Defer** — skip this sitting; leave unoversighted for later.
|
|
47
|
+
|
|
48
|
+
This is a genuine human-decision surface (the point of P288/ADR-068) — `AskUserQuestion` is correct here, not over-asking. Do not auto-confirm; do not prose-ask.
|
|
49
|
+
|
|
50
|
+
### Step 4: Apply the outcome
|
|
51
|
+
|
|
52
|
+
- **Confirm / Amend**: write `human-oversight: confirmed` + `oversight-date: <today, YYYY-MM-DD>` into the file's frontmatter (insert after the `status:`/`date-created:` line if absent; never duplicate). For Amend, apply the directed change first. Edits go through the standard JTBD / architect edit gate per ADR-014.
|
|
53
|
+
- **Reject**: leave the marker absent; record the rework.
|
|
54
|
+
- **Defer**: no write.
|
|
55
|
+
|
|
56
|
+
**Unoversighted ≠ unusable** (ADR-068): an unconfirmed job/persona stays fully readable and review-anchorable. The marker records provenance; it never quarantines the doc or blocks reviews from reading it.
|
|
57
|
+
|
|
58
|
+
### Step 5: Commit + report
|
|
59
|
+
|
|
60
|
+
Commit the confirmed/amended files per ADR-014 (one commit per drain sitting is acceptable). Report: confirmed / amended / rejected / deferred counts, and the remaining unoversighted count (re-run the detector). The session-start nudge count drops by the number confirmed.
|
|
61
|
+
|
|
62
|
+
## Notes
|
|
63
|
+
|
|
64
|
+
- **Never re-ask** — a confirmed job/persona carries the marker permanently and is excluded from future runs (ADR-009). Write-once **except** when the job statement / persona definition is materially rewritten — a material amend clears the marker for re-confirmation (ADR-068 Reassessment).
|
|
65
|
+
- **AFK** — interactive by construction (the confirm IS the human decision); not dispatched in AFK iteration subprocesses. The session-start nudge self-suppresses there (`WR_SUPPRESS_OVERSIGHT_NUDGE=1`).
|
|
66
|
+
- **Born-confirmed going forward** — `/wr-jtbd:update-guide` writes the marker when the user confirms a new/edited job or persona, so new artifacts enter the set already oversighted and the unoversighted count only shrinks.
|
|
67
|
+
|
|
68
|
+
## Related
|
|
69
|
+
|
|
70
|
+
- **ADR-068** — this drain + the marker + detector + nudge. **ADR-066 / P283** — the architect precedent this mirrors.
|
|
71
|
+
- **ADR-008** — JTBD directory structure (the marker is additive to its frontmatter contract).
|
|
72
|
+
- **ADR-009** — never-re-ask persistent-marker principle. **ADR-013 / ADR-044** — structured user interaction + decision-delegation taxonomy.
|
|
73
|
+
- `packages/jtbd/skills/review-jobs/SKILL.md` — the read-only alignment reviewer (distinct from this drain).
|
|
74
|
+
- `packages/jtbd/skills/update-guide/SKILL.md` — born-confirmed write site.
|
|
@@ -89,6 +89,15 @@ Use AskUserQuestion to present the drafted personas and ask:
|
|
|
89
89
|
- Any missing user segments?
|
|
90
90
|
- Any constraints or pain points to add?
|
|
91
91
|
|
|
92
|
+
**Born-confirmed write (ADR-068).** Once the user confirms a persona via this AskUserQuestion pass, write the human-oversight marker into that persona's frontmatter — insert after the `description:` line:
|
|
93
|
+
|
|
94
|
+
```yaml
|
|
95
|
+
human-oversight: confirmed
|
|
96
|
+
oversight-date: YYYY-MM-DD # today
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
This is the born-confirmed gate: a persona authored through update-guide enters the world already human-oversighted (it does not appear in `/wr-jtbd:confirm-jobs-and-personas`' unoversighted set). Do NOT write the marker for a persona the user has not confirmed. The marker is orthogonal to status.
|
|
100
|
+
|
|
92
101
|
### 5. Draft jobs
|
|
93
102
|
|
|
94
103
|
For each job (3-8 per persona), create a file at
|
|
@@ -135,6 +144,15 @@ Use AskUserQuestion to present the drafted jobs and ask:
|
|
|
135
144
|
- Do the job statements ring true?
|
|
136
145
|
- Any missing jobs or user flows?
|
|
137
146
|
|
|
147
|
+
**Born-confirmed write (ADR-068).** Once the user confirms a job via this AskUserQuestion pass, write the human-oversight marker into that job's frontmatter — insert after the `date-created:` line:
|
|
148
|
+
|
|
149
|
+
```yaml
|
|
150
|
+
human-oversight: confirmed
|
|
151
|
+
oversight-date: YYYY-MM-DD # today
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
A job authored through update-guide is born human-oversighted, so the `/wr-jtbd:confirm-jobs-and-personas` unoversighted set only ever shrinks. Do NOT write the marker for a job the user has not confirmed (drafted-but-unconfirmed jobs stay unmarked). The marker is orthogonal to `status:` — a `proposed` job can be `human-oversight: confirmed`.
|
|
155
|
+
|
|
138
156
|
### 7. Generate README.md index
|
|
139
157
|
|
|
140
158
|
Write `docs/jtbd/README.md` with tables grouping jobs by persona and status:
|