@windyroad/itil 0.55.5 → 0.56.0-preview.877
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/bin/wr-itil-check-rfc-has-stories +51 -0
- package/package.json +1 -1
- package/scripts/check-rfc-has-stories.sh +59 -0
- package/scripts/test/check-rfc-has-stories.bats +69 -0
- package/scripts/test/rfc-stories-extension.bats +7 -5
- package/scripts/test/working-the-problem-traversal.bats +11 -4
- package/skills/manage-problem/SKILL.md +3 -3
- package/skills/manage-rfc/SKILL.md +1 -1
- package/skills/work-problem/SKILL.md +1 -1
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Generated by scripts/sync-shim-wrappers.sh from
|
|
3
|
+
# packages/shared/lib/shim-wrapper-template.sh. DO NOT EDIT individual
|
|
4
|
+
# shim files in packages/*/bin/wr-* directly; edit the template + run
|
|
5
|
+
# `npm run sync:shim-wrappers` to regenerate.
|
|
6
|
+
#
|
|
7
|
+
# Resolution (ADR-080):
|
|
8
|
+
# 1. If the wrapper's parent dir is semver-shaped, treat as installed-
|
|
9
|
+
# cache execution and resolve to the highest-version sibling's
|
|
10
|
+
# scripts/ entry below.
|
|
11
|
+
# 2. Otherwise (parent dir is e.g. `architect`), treat as source-
|
|
12
|
+
# monorepo execution and dispatch to own scripts/. The source-repo-
|
|
13
|
+
# guard `exec` is the anchor parsed by
|
|
14
|
+
# packages/retrospective/scripts/check-tarball-shipped-shims.sh.
|
|
15
|
+
# 3. If the cache parent contains zero semver-shaped siblings, exit
|
|
16
|
+
# 127 with a stderr message naming the cache parent (per SQ-080-2).
|
|
17
|
+
#
|
|
18
|
+
# @adr ADR-080 (highest-version-wins shim wrapper plugin scaffold)
|
|
19
|
+
# @adr ADR-049 (plugin-bundled scripts resolve via bin/ on $PATH — amended)
|
|
20
|
+
# @problem P343 (mid-session staleness window)
|
|
21
|
+
|
|
22
|
+
set -euo pipefail
|
|
23
|
+
|
|
24
|
+
SHIM_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
25
|
+
OWN_VERSION_DIR="$(dirname "$SHIM_DIR")"
|
|
26
|
+
OWN_VERSION_NAME="$(basename "$OWN_VERSION_DIR")"
|
|
27
|
+
CACHE_PARENT="$(dirname "$OWN_VERSION_DIR")"
|
|
28
|
+
|
|
29
|
+
SEMVER_RE='^[0-9]+\.[0-9]+\.[0-9]+([-+][0-9A-Za-z.-]+)?$'
|
|
30
|
+
|
|
31
|
+
# Source-repo guard: own parent dir is NOT semver → dispatch to own scripts/.
|
|
32
|
+
if ! [[ "$OWN_VERSION_NAME" =~ $SEMVER_RE ]]; then
|
|
33
|
+
exec "$SHIM_DIR/../scripts/check-rfc-has-stories.sh" "$@"
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Cache execution: pick the highest-semver sibling under CACHE_PARENT.
|
|
37
|
+
HIGHEST=""
|
|
38
|
+
while IFS= read -r dir; do
|
|
39
|
+
name="$(basename "$dir")"
|
|
40
|
+
[[ "$name" =~ $SEMVER_RE ]] || continue
|
|
41
|
+
if [[ -z "$HIGHEST" ]] || [[ "$(printf '%s\n%s\n' "$HIGHEST" "$name" | sort -V | tail -1)" == "$name" ]]; then
|
|
42
|
+
HIGHEST="$name"
|
|
43
|
+
fi
|
|
44
|
+
done < <(find "$CACHE_PARENT" -mindepth 1 -maxdepth 1 -type d 2>/dev/null)
|
|
45
|
+
|
|
46
|
+
if [[ -z "$HIGHEST" ]]; then
|
|
47
|
+
printf 'wr-shim: no cached versions in %s\n' "$CACHE_PARENT" >&2
|
|
48
|
+
exit 127
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
exec "$CACHE_PARENT/$HIGHEST/scripts/check-rfc-has-stories.sh" "$@"
|
package/package.json
CHANGED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# check-rfc-has-stories.sh — ADR-089 (every RFC has at least one story).
|
|
3
|
+
#
|
|
4
|
+
# The load-bearing detection half of the manage-rfc `proposed -> accepted` gate:
|
|
5
|
+
# an RFC must list >=1 story before it can be accepted. Exits non-zero (with a
|
|
6
|
+
# stderr directive) when the RFC's `stories:` frontmatter is empty (`stories: []`)
|
|
7
|
+
# or missing; exits 0 when >=1 `STORY-NNN` is listed (inline or block-list).
|
|
8
|
+
#
|
|
9
|
+
# This removes the pre-ADR-089 empty-stories fallback (the "atomic RFC ships with
|
|
10
|
+
# stories: [] / JTBD-101 friction guard" shape). An atomic fix is now an RFC with
|
|
11
|
+
# exactly one full story, never an empty list.
|
|
12
|
+
#
|
|
13
|
+
# Usage: check-rfc-has-stories.sh <rfc-file>
|
|
14
|
+
# Exit: 0 = >=1 story; 1 = empty/missing stories; 2 = usage / file error.
|
|
15
|
+
#
|
|
16
|
+
# Authority: ADR-089. Driver: P404. Behavioural test: check-rfc-has-stories.bats.
|
|
17
|
+
set -euo pipefail
|
|
18
|
+
|
|
19
|
+
rfc="${1:-}"
|
|
20
|
+
if [ -z "$rfc" ]; then
|
|
21
|
+
echo "check-rfc-has-stories: usage: check-rfc-has-stories.sh <rfc-file>" >&2
|
|
22
|
+
exit 2
|
|
23
|
+
fi
|
|
24
|
+
if [ ! -f "$rfc" ]; then
|
|
25
|
+
echo "check-rfc-has-stories: file not found: $rfc" >&2
|
|
26
|
+
exit 2
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# The frontmatter `stories:` line (first match; frontmatter is at the top).
|
|
30
|
+
stories_line="$(awk '/^stories:/{print; exit}' "$rfc")"
|
|
31
|
+
|
|
32
|
+
if [ -z "$stories_line" ]; then
|
|
33
|
+
echo "check-rfc-has-stories: $rfc has no 'stories:' field — an RFC must list >=1 story (ADR-089). Decompose the fix into >=1 story before accepting." >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Reject an explicit empty inline list: `stories: []`.
|
|
38
|
+
if printf '%s' "$stories_line" | grep -qE '^stories:[[:space:]]*\[[[:space:]]*\][[:space:]]*$'; then
|
|
39
|
+
echo "check-rfc-has-stories: $rfc has empty 'stories: []' — an RFC must list >=1 story (ADR-089; the empty-stories fallback is removed). An atomic fix is an RFC with exactly one full story." >&2
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Accept if a STORY-id appears inline on the stories: line.
|
|
44
|
+
if printf '%s' "$stories_line" | grep -qE 'STORY-[0-9]'; then
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Accept if a YAML block-list under stories: carries >=1 STORY-id.
|
|
49
|
+
if awk '
|
|
50
|
+
/^stories:/ { inblock=1; next }
|
|
51
|
+
inblock && /^[[:space:]]*-[[:space:]]*STORY-[0-9]/ { found=1 }
|
|
52
|
+
inblock && /^[^[:space:]-]/ { exit }
|
|
53
|
+
END { exit !found }
|
|
54
|
+
' "$rfc"; then
|
|
55
|
+
exit 0
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
echo "check-rfc-has-stories: $rfc 'stories:' lists no STORY- ids — an RFC must list >=1 story (ADR-089)." >&2
|
|
59
|
+
exit 1
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bats
|
|
2
|
+
# Behavioural test for check-rfc-has-stories.sh (ADR-089 — every RFC has >=1 story).
|
|
3
|
+
# The predicate exits non-zero when an RFC's `stories:` frontmatter is empty or
|
|
4
|
+
# missing (the empty-stories fallback ADR-089 removes); exit 0 when >=1 story is
|
|
5
|
+
# listed. This is the load-bearing detection half of the proposed->accepted gate.
|
|
6
|
+
#
|
|
7
|
+
# @adr ADR-089 (every RFC has at least one story)
|
|
8
|
+
# @problem P404 (implement ADR-089 + ADR-090)
|
|
9
|
+
|
|
10
|
+
setup() {
|
|
11
|
+
REPO_ROOT="$(cd "$(dirname "$BATS_TEST_FILENAME")/../../../.." && pwd)"
|
|
12
|
+
SCRIPT="${REPO_ROOT}/packages/itil/scripts/check-rfc-has-stories.sh"
|
|
13
|
+
TMPD="$(mktemp -d)"
|
|
14
|
+
}
|
|
15
|
+
teardown() { rm -rf "$TMPD"; }
|
|
16
|
+
|
|
17
|
+
@test "check-rfc-has-stories: empty stories: [] is REJECTED (exit non-zero + directive)" {
|
|
18
|
+
cat > "$TMPD/RFC-901-empty.proposed.md" <<'EOF'
|
|
19
|
+
---
|
|
20
|
+
status: proposed
|
|
21
|
+
problems: [P170]
|
|
22
|
+
stories: []
|
|
23
|
+
---
|
|
24
|
+
# RFC-901: empty
|
|
25
|
+
EOF
|
|
26
|
+
run bash "$SCRIPT" "$TMPD/RFC-901-empty.proposed.md"
|
|
27
|
+
[ "$status" -ne 0 ]
|
|
28
|
+
[[ "$output" == *"stories"* ]]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@test "check-rfc-has-stories: missing stories: field is REJECTED" {
|
|
32
|
+
cat > "$TMPD/RFC-902-none.proposed.md" <<'EOF'
|
|
33
|
+
---
|
|
34
|
+
status: proposed
|
|
35
|
+
problems: [P170]
|
|
36
|
+
---
|
|
37
|
+
# RFC-902: no stories field
|
|
38
|
+
EOF
|
|
39
|
+
run bash "$SCRIPT" "$TMPD/RFC-902-none.proposed.md"
|
|
40
|
+
[ "$status" -ne 0 ]
|
|
41
|
+
[[ "$output" == *"stories"* ]]
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@test "check-rfc-has-stories: inline >=1 story is ACCEPTED (exit 0)" {
|
|
45
|
+
cat > "$TMPD/RFC-903-ok.proposed.md" <<'EOF'
|
|
46
|
+
---
|
|
47
|
+
status: proposed
|
|
48
|
+
problems: [P170]
|
|
49
|
+
stories: [STORY-020, STORY-021]
|
|
50
|
+
---
|
|
51
|
+
# RFC-903: has stories
|
|
52
|
+
EOF
|
|
53
|
+
run bash "$SCRIPT" "$TMPD/RFC-903-ok.proposed.md"
|
|
54
|
+
[ "$status" -eq 0 ]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@test "check-rfc-has-stories: block-list >=1 story is ACCEPTED (exit 0)" {
|
|
58
|
+
cat > "$TMPD/RFC-904-block.proposed.md" <<'EOF'
|
|
59
|
+
---
|
|
60
|
+
status: proposed
|
|
61
|
+
problems: [P170]
|
|
62
|
+
stories:
|
|
63
|
+
- STORY-020
|
|
64
|
+
---
|
|
65
|
+
# RFC-904: block-list stories
|
|
66
|
+
EOF
|
|
67
|
+
run bash "$SCRIPT" "$TMPD/RFC-904-block.proposed.md"
|
|
68
|
+
[ "$status" -eq 0 ]
|
|
69
|
+
}
|
|
@@ -124,13 +124,15 @@ EOF
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
# ---------------------------------------------------------------------------
|
|
127
|
-
# Surface 2b:
|
|
127
|
+
# Surface 2b: renderer tolerates empty stories: [] on a DRAFT RFC
|
|
128
128
|
# ---------------------------------------------------------------------------
|
|
129
129
|
|
|
130
|
-
@test "rfc-stories-extension:
|
|
131
|
-
#
|
|
132
|
-
#
|
|
133
|
-
#
|
|
130
|
+
@test "rfc-stories-extension: renderer tolerates empty stories: [] on a draft RFC (ADR-089: enforced >=1 at accept, not at render)" {
|
|
131
|
+
# Per ADR-089 every RFC has >=1 story, but empty stories: [] is a legal
|
|
132
|
+
# TRANSIENT state on a draft/proposed RFC before the fix is scoped. The
|
|
133
|
+
# renderer must not reject it (that would block drafting); the >=1-story
|
|
134
|
+
# requirement is enforced at the manage-rfc accept gate by the
|
|
135
|
+
# check-rfc-has-stories predicate, not by this renderer.
|
|
134
136
|
cat > docs/rfcs/RFC-002-atomic.proposed.md <<'EOF'
|
|
135
137
|
---
|
|
136
138
|
status: proposed
|
|
@@ -56,12 +56,19 @@ setup() {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
# ---------------------------------------------------------------------------
|
|
59
|
-
# Surface 2: manage-problem
|
|
59
|
+
# Surface 2: manage-problem — empty stories: [] is a legacy/back-fill state,
|
|
60
|
+
# NOT a legitimate atomic fallback (ADR-089: every RFC has >=1 story). The old
|
|
61
|
+
# JTBD-101-friction-guard atomic-RFC-empty-stories fallback is removed; the
|
|
62
|
+
# legacy no-RFC direct-implementation fallback (a distinct path) stays.
|
|
60
63
|
# ---------------------------------------------------------------------------
|
|
61
64
|
|
|
62
|
-
@test "traversal: manage-problem
|
|
63
|
-
|
|
65
|
+
@test "traversal: manage-problem treats empty stories: [] as legacy/back-fill, not a legitimate atomic fallback (ADR-089)" {
|
|
66
|
+
# Positive: the ADR-089 model (>=1 story; back-fill the legacy empty-stories RFC) is named.
|
|
67
|
+
run grep -iE 'ADR-089|back-fill' "$MANAGE_PROBLEM"
|
|
64
68
|
[ "$status" -eq 0 ]
|
|
69
|
+
# Negative: the old atomic-RFC empty-stories fallback legitimation is gone.
|
|
70
|
+
run grep -iE 'atomic-RFC fallback|atomic RFC.*JTBD-101.*friction guard' "$MANAGE_PROBLEM"
|
|
71
|
+
[ "$status" -ne 0 ]
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
@test "traversal: manage-problem names the legacy no-RFC direct-implementation fallback" {
|
|
@@ -89,7 +96,7 @@ setup() {
|
|
|
89
96
|
[ "$status" -eq 0 ]
|
|
90
97
|
}
|
|
91
98
|
|
|
92
|
-
@test "traversal: manage-problem names Refs: RFC-NNN trailer for
|
|
99
|
+
@test "traversal: manage-problem names Refs: RFC-NNN trailer for cross-cutting RFC work (no single story)" {
|
|
93
100
|
run grep -E 'Refs: RFC-' "$MANAGE_PROBLEM"
|
|
94
101
|
[ "$status" -eq 0 ]
|
|
95
102
|
}
|
|
@@ -200,15 +200,15 @@ The Phase 2 working-the-problem traversal makes "implement the fix" concretely t
|
|
|
200
200
|
1. **Read the problem's `## Fix Strategy` section** — extract referenced RFC IDs (anchor links / inline references like `RFC-NNN`). The I13 gate above has already guaranteed an RFC traces the problem; if the `## Fix Strategy` prose itself references none (a freshly auto-created RFC may not yet be cited inline), fall through to the legacy direct-implementation path (step 6 below) using the traced/auto-created RFC.
|
|
201
201
|
2. **For each referenced RFC** (in the order they appear in the Fix Strategy section), read its frontmatter `stories:` array (per ADR-060 line 259, the array is ORDERED — array position IS execution sequence):
|
|
202
202
|
- **Non-empty `stories:` array** (story-decomposed RFC): pick the first story whose lifecycle status is `accepted` or `in-progress` — skip `done` stories that already shipped, skip `draft` stories that aren't ready (the `manage-story <NNN> accepted` gate enforces INVEST shape; a draft story is structurally unready). Continue to step 3.
|
|
203
|
-
- **Empty `stories: []`** (
|
|
203
|
+
- **Empty `stories: []`** (a **legacy** pre-ADR-089 RFC, or one not yet decomposed): per **ADR-089** every RFC has ≥1 story — an empty `stories:` is a **back-fill** state, NOT a legitimate atomic shape. Back-fill the fix's story onto the RFC's story map (add ≥1 story, transition it `accepted` via `manage-story`), then re-traverse from step 2. The empty-stories atomic fallback is removed — do NOT close the problem on a story-less RFC.
|
|
204
204
|
3. **Read the picked story's body** — `## User value` statement (INVEST Valuable), `## Acceptance criteria` (INVEST Testable observable behaviours), `## Implementation notes` (architecture sketches, library decisions). The story's frontmatter `estimated-effort` field (set at `manage-story accepted` transition per I10 INVEST Estimable) sets the appetite for the iteration.
|
|
205
205
|
4. **Implement the story scope** — follow the project's standard development workflow (plan if needed, architect/JTBD review, behavioural tests per ADR-052, single-commit grain per ADR-014). Confine the implementation to the picked story's acceptance criteria; deviating into adjacent unscoped work is a scope-expansion signal — surface it via the `## Scope expansion` AskUserQuestion below.
|
|
206
206
|
5. **Commit with the `Refs: STORY-<NNN>` trailer** (single-trailer vocabulary per ADR-060 line 307 + amendment 2026-05-10 nitpick N2 — same trailer verb whether the commit is the story's first implementation commit or a continuation). On the FIRST commit AFTER the capture commit (subject prefix discriminates: `feat(itil): capture STORY-NNN ...` is the capture; any other subject prefix is an implementation commit), `/wr-itil:manage-story` auto-transitions the story `draft → in-progress`. As acceptance criteria checkboxes are ticked across multiple commits, the same trailer continues to attribute the work.
|
|
207
207
|
6. **Story `done` auto-transition**: when ALL acceptance-criteria checkboxes in the story body are ticked AND the linked RFC reaches `closed`, `/wr-itil:manage-story` auto-transitions the story `in-progress → done`. (When a story's RFC is still `in-progress` but the acceptance criteria are all ticked, the story stays at `in-progress` until the RFC closes — this preserves the trace coupling per ADR-060 line 309.)
|
|
208
|
-
7. **Pick the next not-done story** from the RFC's `stories:` array
|
|
208
|
+
7. **Pick the next not-done story** from the RFC's `stories:` array. Repeat from step 3.
|
|
209
209
|
8. **When all stories under all referenced RFCs are done** — the problem is fix-released. Include the problem doc closure in the final commit (`git mv` to `.verifying.md`, update Status) per ADR-022. Push, create changeset, release per the lean release principle.
|
|
210
210
|
|
|
211
|
-
**
|
|
211
|
+
**Legacy empty-stories back-fill (per ADR-089)**: a pre-ADR-089 RFC whose `stories:` is empty is a **back-fill** case, not an atomic fallback — ADR-089 requires ≥1 story, so the empty-stories atomic dispatch is removed. Decompose the fix into ≥1 story on the RFC's story map (add the story, transition it `accepted`), then traverse it via the normal story path above. The `Refs: RFC-<NNN>` trailer remains valid for **cross-cutting RFC work with no single story** (e.g. an RFC-level enforcement change spanning several files); it is no longer an atomic-empty-stories fallback. Legacy on-disk RFCs still carrying `stories: []` are surfaced for back-fill by `wr-itil-check-rfc-has-stories` at their next `manage-rfc accepted` transition.
|
|
212
212
|
|
|
213
213
|
**Legacy direct-implementation path** (step 1 no-RFCs case): a Phase 1-shape Known Error whose Fix Strategy references no RFCs continues to work via the pre-Phase-2 flow — read the root cause analysis and fix strategy, implement the fix following the project's development workflow, include the problem doc closure in the fix commit (`git mv` to `.verifying.md`, update Status), push + changeset + release. This preserves backwards compatibility with all existing Known Error problems (which were captured before the RFC framework was Phase-1-graduated).
|
|
214
214
|
|
|
@@ -118,7 +118,7 @@ Each transition is a `git mv` + Edit + `git add` (P057 staging trap) + README re
|
|
|
118
118
|
|
|
119
119
|
| Transition | Checks |
|
|
120
120
|
|------------|--------|
|
|
121
|
-
| `proposed → accepted` | All `problems:` entries resolve. Architect re-review PASS. JTBD re-review PASS. `## Scope` populated (not "deferred"). `## Tasks` decomposed (≥ 1 task; not just deferred placeholder). |
|
|
121
|
+
| `proposed → accepted` | All `problems:` entries resolve. Architect re-review PASS. JTBD re-review PASS. `## Scope` populated (not "deferred"). `## Tasks` decomposed (≥ 1 task; not just deferred placeholder). **`stories:` non-empty — run `wr-itil-check-rfc-has-stories <rfc-file>`; hard-block on non-zero exit (empty `stories: []` or missing).** Per **ADR-089** the empty-stories fallback is removed: an atomic fix is an RFC with exactly one full story; an empty `stories:` is permitted only on a `proposed`/draft RFC before the fix is scoped, never at `accepted`. |
|
|
122
122
|
| `accepted → in-progress` | First commit referencing `Refs: RFC-<NNN>` exists OR is being authored in this same commit. I1 hard-block on missing/orphan trace. |
|
|
123
123
|
| `in-progress → verifying` | All `## Tasks` checked. `## Verification` section drafted (release marker, user-side check, trace closure path). I1 hard-block on missing/orphan trace. |
|
|
124
124
|
| `verifying → closed` | User explicitly confirms (or AFK Rule 6 fallback for evidence-based close per ADR-022 / ADR-044 framework-resolved silent dispatch). I1 advisory-with-escalation if driving problems Closed/Parked. |
|
|
@@ -81,7 +81,7 @@ When a single ticket is the strict top, rungs 2-5 are not consulted. When multip
|
|
|
81
81
|
Invoke `/wr-itil:manage-problem <NNN>` via the Skill tool with the selected ticket's ID as the argument. The delegated skill runs the full Working a Problem flow appropriate to the ticket's status:
|
|
82
82
|
|
|
83
83
|
- **Open ticket**: investigate root cause; document findings; create reproduction test; identify workaround; auto-transition to Known Error when root cause + workaround are documented; if the fix is small, proceed straight into implementation.
|
|
84
|
-
- **Known Error**: traverse problem `## Fix Strategy` → referenced RFCs → each RFC's frontmatter `stories:` array (ordered per ADR-060 line 259) → pick first not-done story (status `accepted` or `in-progress`, skipping `done` and `draft`) → implement the picked story scope.
|
|
84
|
+
- **Known Error**: traverse problem `## Fix Strategy` → referenced RFCs → each RFC's frontmatter `stories:` array (ordered per ADR-060 line 259) → pick first not-done story (status `accepted` or `in-progress`, skipping `done` and `draft`) → implement the picked story scope. An empty `stories: []` is a legacy/back-fill state (per **ADR-089** every RFC has ≥1 story — the empty-stories atomic fallback is removed): back-fill a story onto the RFC, don't fall back to a per-RFC atomic dispatch. No-RFC Fix Strategy (Phase 1-shape legacy problems) falls back to direct fix implementation. Each commit carries `Refs: STORY-<NNN>` (or `Refs: RFC-<NNN>` for cross-cutting RFC work with no single story / `Refs: P<NNN>` for legacy direct path). Stories auto-transition `draft → in-progress` on first non-capture commit; auto-transition `in-progress → done` on all-criteria-ticked + linked RFC closed. When all stories under all referenced RFCs are done, include the Known Error → Verification Pending `git mv` in the final commit per ADR-022. The full traversal contract lives in `/wr-itil:manage-problem` § Working a Problem → Known Error subsection (post-Phase-2 rewrite per ADR-060 lines 300-320).
|
|
85
85
|
|
|
86
86
|
**Why delegate rather than re-implement:** the full investigation / transition / fix / release pipeline is a long-lived, policy-governed flow that must stay on a single authoritative workflow. Re-hosting it on a sibling skill would fork the ownership contract and compound maintenance cost. The split skill (this file) owns the *selection* of the next ticket; `/wr-itil:manage-problem <NNN>` owns the *execution*.
|
|
87
87
|
|