@houseofwolvesllc/claude-scrum-skill 1.8.1 → 2.1.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.
@@ -0,0 +1,47 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/EpicSchema.json",
4
+ "title": "EpicSchema",
5
+ "description": "Single epic shape with stories inlined to avoid cross-file $ref resolution ambiguity.",
6
+ "type": "object",
7
+ "required": ["name", "slug", "description"],
8
+ "properties": {
9
+ "name": { "type": "string" },
10
+ "slug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
11
+ "description": { "type": "string" },
12
+ "depends_on": { "type": "array", "items": { "type": "string" } },
13
+ "shared_design_concerns": { "type": "array", "items": { "type": "string" } },
14
+ "slice": {
15
+ "type": "object",
16
+ "properties": {
17
+ "start_line": { "type": "integer", "minimum": 1 },
18
+ "end_line": { "type": "integer", "minimum": 1 }
19
+ }
20
+ },
21
+ "epic_type": { "type": "string", "enum": ["design-spike"] },
22
+ "stories": {
23
+ "type": "array",
24
+ "items": { "$ref": "#/$defs/Story" }
25
+ }
26
+ },
27
+ "additionalProperties": false,
28
+ "$defs": {
29
+ "Story": {
30
+ "type": "object",
31
+ "required": ["title", "slug", "acceptance_criteria", "points", "executor"],
32
+ "properties": {
33
+ "title": { "type": "string" },
34
+ "slug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
35
+ "acceptance_criteria": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
36
+ "technical_context": { "type": "string" },
37
+ "points": { "type": "integer", "enum": [1, 2, 3, 5, 8, 13] },
38
+ "executor": { "type": "string", "enum": ["claude", "human", "cowork"] },
39
+ "priority": { "type": "string", "enum": ["P0-critical", "P1-high", "P2-medium", "P3-low"] },
40
+ "persona": { "type": "string", "enum": ["impl", "ops", "research"] },
41
+ "blocked_by": { "type": "array", "items": { "type": "string" } },
42
+ "blocks": { "type": "array", "items": { "type": "string" } },
43
+ "labels": { "type": "array", "items": { "type": "string" } }
44
+ }
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/PRDFrontmatterSchema.json",
4
+ "title": "PRDFrontmatterSchema",
5
+ "description": "YAML frontmatter parsed from PRD documents. All fields optional.",
6
+ "type": "object",
7
+ "properties": {
8
+ "title": { "type": "string" },
9
+ "scaffold_mode": {
10
+ "type": "string",
11
+ "enum": ["single-pass", "two-pass"]
12
+ },
13
+ "design_spike": { "type": "boolean" },
14
+ "depends_on": {
15
+ "type": "array",
16
+ "items": { "type": "string" },
17
+ "description": "Other PRD specs (path or basename) that must complete before this one in sequential multi-path mode."
18
+ }
19
+ },
20
+ "additionalProperties": false
21
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/ReviewVerdictSchema.json",
4
+ "title": "ReviewVerdictSchema",
5
+ "description": "Output of a single review pass (per-lens verdict in review_panel.js, or single-pass review in older skills).",
6
+ "type": "object",
7
+ "required": ["recommendation", "findings", "summary"],
8
+ "properties": {
9
+ "recommendation": {
10
+ "type": "string",
11
+ "enum": ["accept", "accept-with-followups", "block"]
12
+ },
13
+ "findings": {
14
+ "type": "object",
15
+ "required": ["critical", "warning", "info"],
16
+ "properties": {
17
+ "critical": {
18
+ "type": "array",
19
+ "items": { "$ref": "#/$defs/Finding" }
20
+ },
21
+ "warning": {
22
+ "type": "array",
23
+ "items": { "$ref": "#/$defs/Finding" }
24
+ },
25
+ "info": {
26
+ "type": "array",
27
+ "items": { "$ref": "#/$defs/Finding" }
28
+ }
29
+ }
30
+ },
31
+ "summary": {
32
+ "type": "string",
33
+ "description": "Reviewer's one-paragraph summary of the pass."
34
+ },
35
+ "lens": {
36
+ "type": "string",
37
+ "enum": ["correctness", "security", "style", "tests"],
38
+ "description": "Set by review_panel.js when running multi-lens; absent in single-pass review."
39
+ }
40
+ },
41
+ "additionalProperties": false,
42
+ "$defs": {
43
+ "Finding": {
44
+ "type": "object",
45
+ "required": ["title", "severity", "body"],
46
+ "properties": {
47
+ "title": { "type": "string" },
48
+ "location": {
49
+ "type": "string",
50
+ "description": "file:line or section reference; optional but recommended."
51
+ },
52
+ "severity": {
53
+ "type": "string",
54
+ "enum": ["critical", "warning", "info"]
55
+ },
56
+ "body": { "type": "string" }
57
+ },
58
+ "additionalProperties": false
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/ScaffoldOutputSchema.json",
4
+ "title": "ScaffoldOutputSchema",
5
+ "description": "Output of /project-scaffold; consumed by /project-orchestrate Step 1 to scope the run.",
6
+ "type": "object",
7
+ "required": ["scope", "scopedEpics", "scopedStories"],
8
+ "properties": {
9
+ "scope": {
10
+ "type": "string",
11
+ "enum": ["prd", "all"],
12
+ "description": "Whether the run is PRD-scoped or covers all open epics."
13
+ },
14
+ "scopedEpics": {
15
+ "type": "array",
16
+ "items": { "type": "string" },
17
+ "description": "Epic slugs (local mode) or milestone numbers (remote mode) created/touched by this scaffold."
18
+ },
19
+ "scopedStories": {
20
+ "type": "array",
21
+ "items": { "type": "string" },
22
+ "description": "Story slugs or issue numbers created/touched by this scaffold."
23
+ },
24
+ "designSpikeEpic": {
25
+ "type": "string",
26
+ "description": "Slug of the auto-injected design-spike epic, if any."
27
+ },
28
+ "queueStateFilePath": {
29
+ "type": "string",
30
+ "description": "Path to orchestration-queue-state.md when multi-path mode is in effect."
31
+ }
32
+ },
33
+ "additionalProperties": false
34
+ }
@@ -0,0 +1,78 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/SpecSchema.json",
4
+ "title": "SpecSchema",
5
+ "description": "Output shape of /project-spec, consumed by /project-scaffold. Inlined to avoid cross-file $ref resolution ambiguity.",
6
+ "type": "object",
7
+ "required": ["title", "overview", "objectives", "epics"],
8
+ "properties": {
9
+ "title": { "type": "string" },
10
+ "overview": { "type": "string" },
11
+ "objectives": {
12
+ "type": "object",
13
+ "required": ["primary"],
14
+ "properties": {
15
+ "primary": { "type": "array", "items": { "type": "string" } },
16
+ "secondary": { "type": "array", "items": { "type": "string" } }
17
+ }
18
+ },
19
+ "epics": {
20
+ "type": "array",
21
+ "items": { "$ref": "#/$defs/Epic" }
22
+ },
23
+ "dependencies": {
24
+ "type": "array",
25
+ "items": { "type": "string" }
26
+ },
27
+ "design_concerns": {
28
+ "type": "array",
29
+ "items": { "type": "string" }
30
+ },
31
+ "scaffold_mode": {
32
+ "type": "string",
33
+ "enum": ["single-pass", "two-pass"]
34
+ },
35
+ "design_spike": { "type": "boolean" }
36
+ },
37
+ "additionalProperties": false,
38
+ "$defs": {
39
+ "Epic": {
40
+ "type": "object",
41
+ "required": ["name", "slug", "description"],
42
+ "properties": {
43
+ "name": { "type": "string" },
44
+ "slug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
45
+ "description": { "type": "string" },
46
+ "subdomain": { "type": "string", "enum": ["core", "supporting", "generic"] },
47
+ "depends_on": { "type": "array", "items": { "type": "string" } },
48
+ "shared_design_concerns": { "type": "array", "items": { "type": "string" } },
49
+ "slice": {
50
+ "type": "object",
51
+ "properties": {
52
+ "start_line": { "type": "integer", "minimum": 1 },
53
+ "end_line": { "type": "integer", "minimum": 1 }
54
+ }
55
+ },
56
+ "epic_type": { "type": "string", "enum": ["design-spike"] },
57
+ "stories": { "type": "array", "items": { "$ref": "#/$defs/Story" } }
58
+ }
59
+ },
60
+ "Story": {
61
+ "type": "object",
62
+ "required": ["title", "slug", "acceptance_criteria", "points", "executor"],
63
+ "properties": {
64
+ "title": { "type": "string" },
65
+ "slug": { "type": "string", "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$" },
66
+ "acceptance_criteria": { "type": "array", "items": { "type": "string" }, "minItems": 1 },
67
+ "technical_context": { "type": "string" },
68
+ "points": { "type": "integer", "enum": [1, 2, 3, 5, 8, 13] },
69
+ "executor": { "type": "string", "enum": ["claude", "human", "cowork"] },
70
+ "priority": { "type": "string", "enum": ["P0-critical", "P1-high", "P2-medium", "P3-low"] },
71
+ "persona": { "type": "string", "enum": ["impl", "ops", "research"] },
72
+ "blocked_by": { "type": "array", "items": { "type": "string" } },
73
+ "blocks": { "type": "array", "items": { "type": "string" } },
74
+ "labels": { "type": "array", "items": { "type": "string" } }
75
+ }
76
+ }
77
+ }
78
+ }
@@ -0,0 +1,42 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/SprintStoryReturnSchema.json",
4
+ "title": "SprintStoryReturnSchema",
5
+ "description": "Per-story return value from sprint_pipeline.js. The calling skill persists results to state file and story frontmatter.",
6
+ "type": "object",
7
+ "required": ["storySlug", "status"],
8
+ "properties": {
9
+ "storySlug": {
10
+ "type": "string",
11
+ "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
12
+ },
13
+ "status": {
14
+ "type": "string",
15
+ "enum": ["done", "blocked", "failed"]
16
+ },
17
+ "branch": {
18
+ "type": "string",
19
+ "description": "Story branch name created during implementation (e.g., story/12-auth-endpoint)."
20
+ },
21
+ "prUrl": {
22
+ "type": "string",
23
+ "format": "uri",
24
+ "description": "GitHub mode only. PR URL opened by the story branch."
25
+ },
26
+ "commits": {
27
+ "type": "array",
28
+ "items": { "type": "string" },
29
+ "description": "Commit SHAs produced by the story."
30
+ },
31
+ "blockers": {
32
+ "type": "array",
33
+ "items": { "type": "string" },
34
+ "description": "Free-text descriptions of why the story is blocked. Populated when status = blocked."
35
+ },
36
+ "reason": {
37
+ "type": "string",
38
+ "description": "Free-text explanation when status = failed or blocked."
39
+ }
40
+ },
41
+ "additionalProperties": false
42
+ }
@@ -0,0 +1,56 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/houseofwolvesllc/claudescrumskill/schemas/StorySchema.json",
4
+ "title": "StorySchema",
5
+ "description": "Single story shape produced by Pass 2 elaboration; consumed by sprint planning and execution.",
6
+ "type": "object",
7
+ "required": ["title", "slug", "acceptance_criteria", "points", "executor"],
8
+ "properties": {
9
+ "title": { "type": "string" },
10
+ "slug": {
11
+ "type": "string",
12
+ "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
13
+ },
14
+ "acceptance_criteria": {
15
+ "type": "array",
16
+ "items": { "type": "string" },
17
+ "minItems": 1
18
+ },
19
+ "technical_context": {
20
+ "type": "string",
21
+ "description": "Architecture notes, relevant files, approach guidance. May be empty if the story body is self-explanatory."
22
+ },
23
+ "points": {
24
+ "type": "integer",
25
+ "enum": [1, 2, 3, 5, 8, 13],
26
+ "description": "Fibonacci estimate per CONVENTIONS.md story point guidelines."
27
+ },
28
+ "executor": {
29
+ "type": "string",
30
+ "enum": ["claude", "human", "cowork"]
31
+ },
32
+ "priority": {
33
+ "type": "string",
34
+ "enum": ["P0-critical", "P1-high", "P2-medium", "P3-low"]
35
+ },
36
+ "persona": {
37
+ "type": "string",
38
+ "enum": ["impl", "ops", "research"],
39
+ "description": "Subagent posture preamble selection. Default is impl."
40
+ },
41
+ "blocked_by": {
42
+ "type": "array",
43
+ "items": { "type": "string" },
44
+ "description": "Slugs (or epic/slug references) of stories that must complete first."
45
+ },
46
+ "blocks": {
47
+ "type": "array",
48
+ "items": { "type": "string" }
49
+ },
50
+ "labels": {
51
+ "type": "array",
52
+ "items": { "type": "string" }
53
+ }
54
+ },
55
+ "additionalProperties": false
56
+ }
@@ -0,0 +1,264 @@
1
+ // sprint_pipeline.js — per-story sprint execution as a pipeline.
2
+ //
3
+ // Invoked by /project-orchestrate Phase 1 Step 3. Replaces the v1.x
4
+ // Task-spawning prose with per-stage barrier removal and concurrency up
5
+ // to min(16, cpu_cores - 2) per the Workflow tool's cap.
6
+ //
7
+ // args: {
8
+ // stories: Story[], // StorySchema-shaped
9
+ // epicSlug: string,
10
+ // releaseBranch: string, // "release/<epic-slug>"
11
+ // contextMdPath?: string, // <paths.context>/<epicSlug>/CONTEXT.md
12
+ // claudeMdPath?: string, // project CLAUDE.md
13
+ // backendMode: "local" | "github" | "jira" | "trello",
14
+ // repoIdentifier?: string, // "owner/repo" — github mode only
15
+ // personaPreambles: Record<string, string>, // persona name → preamble text
16
+ // baselinePath?: string, // shared/references/ENGINEERING_BASELINE.md — injected into every story
17
+ // situationalGuidance?: string[] // SKILL.md paths (design-patterns, domain-modeling) — core-domain epics only
18
+ // }
19
+ //
20
+ // returns: SprintStoryReturn[] (one per story; failed items filtered to null upstream)
21
+
22
+ export const meta = {
23
+ name: 'sprint-pipeline',
24
+ description: 'Per-story sprint execution: implement → review → verify → open PR',
25
+ phases: [
26
+ { title: 'Implement' },
27
+ { title: 'Review' },
28
+ { title: 'Verify' },
29
+ { title: 'Open PR' },
30
+ ],
31
+ }
32
+
33
+ const REVIEW_VERDICT_SCHEMA = {
34
+ type: 'object',
35
+ required: ['recommendation', 'findings', 'summary'],
36
+ properties: {
37
+ recommendation: { type: 'string', enum: ['accept', 'accept-with-followups', 'block'] },
38
+ findings: {
39
+ type: 'object',
40
+ required: ['critical', 'warning', 'info'],
41
+ properties: {
42
+ critical: { type: 'array' },
43
+ warning: { type: 'array' },
44
+ info: { type: 'array' },
45
+ },
46
+ },
47
+ summary: { type: 'string' },
48
+ },
49
+ }
50
+
51
+ const IMPL_RETURN_SCHEMA = {
52
+ type: 'object',
53
+ required: ['storySlug', 'branch', 'commits'],
54
+ properties: {
55
+ storySlug: { type: 'string' },
56
+ branch: { type: 'string' },
57
+ commits: { type: 'array', items: { type: 'string' } },
58
+ notes: { type: 'string' },
59
+ },
60
+ }
61
+
62
+ const VERIFY_RETURN_SCHEMA = {
63
+ type: 'object',
64
+ required: ['storySlug', 'verifyStatus'],
65
+ properties: {
66
+ storySlug: { type: 'string' },
67
+ verifyStatus: { type: 'string', enum: ['pass', 'warn', 'fail'] },
68
+ notes: { type: 'string' },
69
+ },
70
+ }
71
+
72
+ const SPRINT_STORY_RETURN_SCHEMA = {
73
+ type: 'object',
74
+ required: ['storySlug', 'status'],
75
+ properties: {
76
+ storySlug: { type: 'string' },
77
+ status: { type: 'string', enum: ['done', 'blocked', 'failed'] },
78
+ branch: { type: 'string' },
79
+ prUrl: { type: 'string' },
80
+ commits: { type: 'array', items: { type: 'string' } },
81
+ blockers: { type: 'array', items: { type: 'string' } },
82
+ reason: { type: 'string' },
83
+ },
84
+ }
85
+
86
+ /**
87
+ * Build a SprintStoryReturn-shaped object for short-circuit paths
88
+ * (review-block, verify-fail). The shape conforms to
89
+ * SPRINT_STORY_RETURN_SCHEMA above; keeping the helper alongside ensures
90
+ * any future schema change requires updating both at once.
91
+ */
92
+ function makeSprintStoryReturn({ storySlug, status, branch, commits, prUrl, blockers, reason }) {
93
+ const out = { storySlug, status }
94
+ if (branch !== undefined) out.branch = branch
95
+ if (commits !== undefined) out.commits = commits
96
+ if (prUrl !== undefined) out.prUrl = prUrl
97
+ if (blockers !== undefined) out.blockers = blockers
98
+ if (reason !== undefined) out.reason = reason
99
+ return out
100
+ }
101
+
102
+ const {
103
+ stories,
104
+ epicSlug,
105
+ releaseBranch,
106
+ contextMdPath,
107
+ claudeMdPath,
108
+ backendMode,
109
+ repoIdentifier,
110
+ personaPreambles = {},
111
+ baselinePath,
112
+ situationalGuidance = [],
113
+ } = args
114
+
115
+ if (!stories || stories.length === 0) {
116
+ log('No stories in sprint — exiting.')
117
+ return []
118
+ }
119
+
120
+ log(`Sprint pipeline: ${stories.length} stories on release branch ${releaseBranch} (backend=${backendMode}).`)
121
+
122
+ function buildImplementPrompt(story) {
123
+ const persona = story.persona || 'impl'
124
+ const preamble = personaPreambles[persona] || ''
125
+ const claudeMdLine = claudeMdPath
126
+ ? `Before writing any code, read ${claudeMdPath} and follow every convention.`
127
+ : 'Read the project CLAUDE.md (if present) and follow every convention.'
128
+ const contextLine = contextMdPath
129
+ ? `Before writing any code, read ${contextMdPath} if it exists. Its Naming, File Layout, Shared Types, and Patterns sections are binding for this epic — they override generic CLAUDE.md conventions for this epic.`
130
+ : ''
131
+ const baselineLine = baselinePath
132
+ ? `Before writing any code, read ${baselinePath} — the universal engineering baseline (Clean Code, Test-Driven Development, and the simple-design Arbitration Rule). Follow it for all code: write tests first (red-green-refactor), keep designs simple, and treat the Arbitration Rule as binding. On a direct conflict the project CLAUDE.md wins.`
133
+ : ''
134
+ const situationalLine = situationalGuidance.length
135
+ ? `This is a core-domain story. Also read and apply: ${situationalGuidance.join(', ')}. These are situational guidance and remain subordinate to the baseline's Arbitration Rule — model the domain's invariants first, and reach for a design pattern or domain layer only when a demonstrated axis of variation or an essential business rule warrants it, never speculatively.`
136
+ : ''
137
+ return `${preamble}
138
+
139
+ ---
140
+
141
+ You are implementing story ${story.slug} on release branch ${releaseBranch}.
142
+
143
+ ${claudeMdLine}
144
+ ${baselineLine}
145
+ ${situationalLine}
146
+ ${contextLine}
147
+
148
+ **Story:** ${story.title}
149
+ **Acceptance criteria:**
150
+ ${(story.acceptance_criteria || []).map(c => ` - ${c}`).join('\n')}
151
+
152
+ **Technical context:** ${story.technical_context || '(none provided)'}
153
+
154
+ **Branch strategy:** Create branch \`story/${story.slug}\` from \`${releaseBranch}\`. Implement. Commit with a clear message. Return the branch name, the commit SHAs, and any notes.
155
+
156
+ Do NOT open a PR yet. Do NOT merge. The next stage handles review.`
157
+ }
158
+
159
+ function buildReviewPrompt(impl, story) {
160
+ return `You are reviewing the implementation of story ${story.slug} on branch ${impl.branch}.
161
+
162
+ Read the diff between ${releaseBranch} and ${impl.branch}.
163
+
164
+ Story acceptance criteria:
165
+ ${(story.acceptance_criteria || []).map(c => ` - ${c}`).join('\n')}
166
+
167
+ Review for: correctness against acceptance criteria, project convention compliance (per CLAUDE.md${baselinePath ? ` and the engineering baseline at ${baselinePath}` : ''}), and obvious defects. ${baselinePath ? 'Confirm the baseline was honored: tests accompany the code and the design is the simplest that satisfies the story (no unearned abstraction). ' : ''}Do NOT bikeshed style the project doesn't enforce.
168
+
169
+ Return a ReviewVerdict: recommendation (accept | accept-with-followups | block), findings grouped by severity, and a one-paragraph summary.`
170
+ }
171
+
172
+ function buildVerifyPrompt(review, story) {
173
+ return `You are running a lightweight verification on story ${story.slug}.
174
+
175
+ If the project has a build/lint/test command, run it on the story branch. If not, perform a smoke read of the changed files to confirm no obvious runtime defects (broken imports, syntax errors, dangling references).
176
+
177
+ Return verifyStatus (pass | warn | fail) and brief notes.`
178
+ }
179
+
180
+ function buildOpenPRPrompt(verify, story, impl) {
181
+ const ghOrLocal =
182
+ backendMode === 'github'
183
+ ? `Open a PR via gh CLI targeting ${releaseBranch}. Capture the PR URL.`
184
+ : `Merge story/${story.slug} into ${releaseBranch} locally. Capture the merge commit SHA.`
185
+ return `You are finalizing story ${story.slug}.
186
+
187
+ Verify status: ${verify.verifyStatus}. Review recommendation: (from prior stage).
188
+
189
+ ${ghOrLocal}
190
+
191
+ Return SprintStoryReturn: storySlug, status (done | blocked | failed), branch, prUrl (github mode) or merge commit (local mode), commits[], blockers[] (if blocked), reason (if failed).`
192
+ }
193
+
194
+ phase('Implement')
195
+ phase('Review')
196
+ phase('Verify')
197
+ phase('Open PR')
198
+
199
+ const results = await pipeline(
200
+ stories,
201
+ // Stage 1: Implement
202
+ story =>
203
+ agent(buildImplementPrompt(story), {
204
+ label: `impl:${story.slug}`,
205
+ phase: 'Implement',
206
+ schema: IMPL_RETURN_SCHEMA,
207
+ }),
208
+ // Stage 2: Review
209
+ (impl, story) =>
210
+ impl
211
+ ? agent(buildReviewPrompt(impl, story), {
212
+ label: `review:${story.slug}`,
213
+ phase: 'Review',
214
+ schema: REVIEW_VERDICT_SCHEMA,
215
+ }).then(review => ({ impl, review }))
216
+ : null,
217
+ // Stage 3: Verify
218
+ (prev, story) =>
219
+ prev
220
+ ? agent(buildVerifyPrompt(prev.review, story), {
221
+ label: `verify:${story.slug}`,
222
+ phase: 'Verify',
223
+ schema: VERIFY_RETURN_SCHEMA,
224
+ }).then(verify => ({ ...prev, verify }))
225
+ : null,
226
+ // Stage 4: Open PR (or local merge)
227
+ (prev, story) => {
228
+ if (!prev) return null
229
+ const { impl, review, verify } = prev
230
+ // If the reviewer said block, short-circuit to blocked status without an openPR call.
231
+ if (review.recommendation === 'block') {
232
+ const blockers = [
233
+ ...review.findings.critical.map(f => f.title),
234
+ ...review.findings.warning.map(f => f.title),
235
+ ]
236
+ return makeSprintStoryReturn({
237
+ storySlug: story.slug,
238
+ status: 'blocked',
239
+ branch: impl.branch,
240
+ commits: impl.commits,
241
+ blockers,
242
+ reason: 'Review recommended block.',
243
+ })
244
+ }
245
+ // If verify failed, also short-circuit.
246
+ if (verify.verifyStatus === 'fail') {
247
+ return makeSprintStoryReturn({
248
+ storySlug: story.slug,
249
+ status: 'blocked',
250
+ branch: impl.branch,
251
+ commits: impl.commits,
252
+ blockers: [verify.notes || 'verification failed'],
253
+ reason: 'Verification failed.',
254
+ })
255
+ }
256
+ return agent(buildOpenPRPrompt(verify, story, impl), {
257
+ label: `pr:${story.slug}`,
258
+ phase: 'Open PR',
259
+ schema: SPRINT_STORY_RETURN_SCHEMA,
260
+ })
261
+ }
262
+ )
263
+
264
+ return results.filter(Boolean)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@houseofwolvesllc/claude-scrum-skill",
3
- "version": "1.8.1",
3
+ "version": "2.1.0",
4
4
  "description": "Claude Code skills for scrum project management — PRD to production release pipeline with project scaffolding, sprint planning, status tracking, sprint releases, full-project emulation testing, autonomous orchestration, and project cleanup.",
5
5
  "bin": {},
6
6
  "publishConfig": {
@@ -32,6 +32,7 @@
32
32
  "files": [
33
33
  ".claude-plugin/",
34
34
  "skills/",
35
- "bin/"
35
+ "bin/",
36
+ "lib/"
36
37
  ]
37
38
  }