@pennyfarthing/core 7.6.0 → 7.7.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.
- package/README.md +109 -201
- package/package.json +1 -1
- package/packages/core/dist/cli/commands/doctor.d.ts.map +1 -1
- package/packages/core/dist/cli/commands/doctor.js +91 -0
- package/packages/core/dist/cli/commands/doctor.js.map +1 -1
- package/packages/core/dist/cli/commands/init.js +31 -0
- package/packages/core/dist/cli/commands/init.js.map +1 -1
- package/packages/core/dist/cli/commands/update.js +31 -0
- package/packages/core/dist/cli/commands/update.js.map +1 -1
- package/pennyfarthing-dist/agents/architect.md +48 -53
- package/pennyfarthing-dist/agents/dev.md +74 -164
- package/pennyfarthing-dist/agents/devops.md +44 -39
- package/pennyfarthing-dist/agents/handoff.md +46 -23
- package/pennyfarthing-dist/agents/orchestrator.md +84 -255
- package/pennyfarthing-dist/agents/pm.md +40 -50
- package/pennyfarthing-dist/agents/reviewer-preflight.md +58 -26
- package/pennyfarthing-dist/agents/reviewer.md +107 -298
- package/pennyfarthing-dist/agents/sm-file-summary.md +51 -30
- package/pennyfarthing-dist/agents/sm-finish.md +59 -38
- package/pennyfarthing-dist/agents/sm-handoff.md +40 -33
- package/pennyfarthing-dist/agents/sm-setup.md +89 -47
- package/pennyfarthing-dist/agents/sm.md +171 -558
- package/pennyfarthing-dist/agents/tea.md +77 -146
- package/pennyfarthing-dist/agents/tech-writer.md +43 -24
- package/pennyfarthing-dist/agents/testing-runner.md +73 -30
- package/pennyfarthing-dist/agents/ux-designer.md +39 -25
- package/pennyfarthing-dist/agents/workflow-status-check.md +34 -16
- package/pennyfarthing-dist/commands/benchmark.md +19 -1
- package/pennyfarthing-dist/commands/continue-session.md +1 -1
- package/pennyfarthing-dist/commands/solo.md +5 -0
- package/pennyfarthing-dist/commands/theme-maker.md +5 -5
- package/pennyfarthing-dist/commands/work.md +1 -1
- package/pennyfarthing-dist/guides/XML-TAGS.md +179 -0
- package/pennyfarthing-dist/guides/agent-behavior.md +37 -2
- package/pennyfarthing-dist/guides/agent-tag-taxonomy.md +432 -0
- package/pennyfarthing-dist/guides/patterns/approval-gates-pattern.md +27 -7
- package/pennyfarthing-dist/guides/scale-levels.md +114 -0
- package/pennyfarthing-dist/personas/themes/gilligans-island.yaml +2 -2
- package/pennyfarthing-dist/personas/themes/star-trek-tos.yaml +1 -1
- package/pennyfarthing-dist/scripts/core/agent-session.sh +13 -7
- package/pennyfarthing-dist/scripts/core/check-context.sh +25 -8
- package/pennyfarthing-dist/scripts/core/prime.sh +57 -32
- package/pennyfarthing-dist/scripts/git/create-feature-branches.sh +45 -4
- package/pennyfarthing-dist/scripts/git/git-status-all.sh +32 -7
- package/pennyfarthing-dist/scripts/hooks/bell-mode-hook.sh +30 -11
- package/pennyfarthing-dist/scripts/hooks/pre-commit.sh +80 -23
- package/pennyfarthing-dist/scripts/hooks/question-reflector-check.mjs +393 -0
- package/pennyfarthing-dist/scripts/hooks/question-reflector-check.sh +20 -0
- package/pennyfarthing-dist/scripts/hooks/question_reflector_check.py +402 -0
- package/pennyfarthing-dist/scripts/hooks/session-stop.sh +7 -0
- package/pennyfarthing-dist/scripts/hooks/tests/question-reflector.test.mjs +545 -0
- package/pennyfarthing-dist/scripts/hooks/welcome-hook.sh +94 -0
- package/pennyfarthing-dist/scripts/jira/jira-claim-story.sh +10 -152
- package/pennyfarthing-dist/scripts/jira/jira-sync-story.sh +14 -4
- package/pennyfarthing-dist/scripts/jira/jira-sync.sh +12 -4
- package/pennyfarthing-dist/scripts/jira/sync-epic-jira.sh +11 -99
- package/pennyfarthing-dist/scripts/lib/common.sh +55 -0
- package/pennyfarthing-dist/scripts/maintenance/sidecar-health.sh +97 -0
- package/pennyfarthing-dist/scripts/misc/deploy.sh +13 -1
- package/pennyfarthing-dist/scripts/misc/statusline.sh +27 -22
- package/pennyfarthing-dist/scripts/story/create-story.sh +14 -154
- package/pennyfarthing-dist/scripts/story/size-story.sh +12 -192
- package/pennyfarthing-dist/scripts/story/story-template.sh +12 -156
- package/pennyfarthing-dist/scripts/test/ground-truth-judge.py +24 -93
- package/pennyfarthing-dist/scripts/test/swebench-judge.py +33 -59
- package/pennyfarthing-dist/scripts/validation/validate-agent-schema.sh +575 -0
- package/pennyfarthing-dist/scripts/workflow/check.py +502 -0
- package/pennyfarthing-dist/skills/skill-registry.yaml +52 -16
- package/pennyfarthing-dist/skills/sprint/skill.md +1 -1
- package/pennyfarthing-dist/templates/settings.local.json.template +11 -0
|
@@ -5,57 +5,78 @@ tools: Bash, Read
|
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
<arguments>
|
|
9
|
+
| Argument | Required | Description |
|
|
10
|
+
|----------|----------|-------------|
|
|
11
|
+
| `STORY_ID` | Yes | Story identifier, e.g., "31-10" |
|
|
12
|
+
| `JIRA_KEY` | No | Jira issue key (skip Jira checks if absent) |
|
|
13
|
+
| `REPOS` | Yes | Repository name(s) |
|
|
14
|
+
| `BRANCH` | Yes | Feature branch name |
|
|
15
|
+
</arguments>
|
|
14
16
|
|
|
15
|
-
<
|
|
16
|
-
Run
|
|
17
|
-
</critical>
|
|
17
|
+
<execution>
|
|
18
|
+
## Run Preflight Script
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
## Parallel Checks
|
|
20
|
+
The preflight script runs all checks in parallel using asyncio:
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
4. **Acceptance Criteria:** grep checkboxes from session file
|
|
26
|
-
5. **Cleanup:** remove temp files from `.session/`
|
|
27
|
-
</gate>
|
|
22
|
+
```bash
|
|
23
|
+
source .venv/bin/activate && python -m pennyfarthing_scripts.preflight finish {STORY_ID} --branch {BRANCH} --jira {JIRA_KEY}
|
|
24
|
+
```
|
|
28
25
|
|
|
29
|
-
|
|
26
|
+
If no JIRA_KEY, omit the `--jira` flag.
|
|
27
|
+
|
|
28
|
+
The script returns JSON with:
|
|
29
|
+
- `status`: "success" or "blocked"
|
|
30
|
+
- `ready_to_finish`: boolean
|
|
31
|
+
- `issues`: array of blocking issues
|
|
32
|
+
- `warnings`: array of non-blocking warnings
|
|
33
|
+
- `next_steps`: array of recommended actions
|
|
34
|
+
</execution>
|
|
30
35
|
|
|
31
36
|
<critical>
|
|
37
|
+
## Jira Transition
|
|
38
|
+
|
|
32
39
|
The Jira transition to Done is handled by `/story finish` (finish-story.sh).
|
|
33
40
|
Do NOT transition Jira here - that would duplicate the finish script's work.
|
|
34
41
|
This subagent only performs preflight checks and assessment.
|
|
35
42
|
</critical>
|
|
36
43
|
|
|
37
|
-
|
|
44
|
+
<output>
|
|
45
|
+
## Output Format
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
Parse the JSON output from the preflight script and return a `FINISH_PREFLIGHT_RESULT` block.
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
49
|
+
### Ready to Finish
|
|
50
|
+
```yaml
|
|
51
|
+
FINISH_PREFLIGHT_RESULT:
|
|
52
|
+
status: success
|
|
53
|
+
ready_to_finish: true
|
|
54
|
+
story_id: "{story_id from JSON}"
|
|
55
|
+
pr:
|
|
56
|
+
state: "{pr.state from JSON}"
|
|
57
|
+
merged: {pr.merged from JSON}
|
|
58
|
+
url: "{pr.url from JSON}"
|
|
59
|
+
lint:
|
|
60
|
+
clean: {lint.clean from JSON}
|
|
61
|
+
jira:
|
|
62
|
+
current: "{jira.current from JSON}"
|
|
63
|
+
key: "{jira.key from JSON}"
|
|
64
|
+
acceptance_criteria:
|
|
65
|
+
total: {acceptance_criteria.total from JSON}
|
|
66
|
+
checked: {acceptance_criteria.checked from JSON}
|
|
67
|
+
next_steps: {next_steps array from JSON}
|
|
51
68
|
```
|
|
52
69
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
70
|
+
### Not Ready
|
|
71
|
+
```yaml
|
|
72
|
+
FINISH_PREFLIGHT_RESULT:
|
|
73
|
+
status: blocked
|
|
74
|
+
ready_to_finish: false
|
|
75
|
+
issues: {issues array from JSON}
|
|
76
|
+
warnings: {warnings array from JSON}
|
|
77
|
+
next_steps: {next_steps array from JSON}
|
|
78
|
+
```
|
|
59
79
|
|
|
60
|
-
|
|
61
|
-
|
|
80
|
+
### Jira Skipped
|
|
81
|
+
If `jira_skipped: true` in JSON, note this in output.
|
|
82
|
+
</output>
|
|
@@ -19,24 +19,27 @@ This subagent verifies prerequisites and updates session file only.
|
|
|
19
19
|
Return `HANDOFF_RESULT` with the next agent name - SM runs `handoff-marker.sh` as their last action.
|
|
20
20
|
</critical>
|
|
21
21
|
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
<arguments>
|
|
23
|
+
| Argument | Required | Description |
|
|
24
|
+
|----------|----------|-------------|
|
|
25
|
+
| `STORY_ID` | Yes | Story identifier, e.g., "31-10" |
|
|
26
|
+
| `NEXT_AGENT` | Yes | Target agent: `tea` or `dev` |
|
|
27
|
+
| `NEXT_PHASE` | Yes | Target phase: `red` (TEA) or `implement` (Dev) |
|
|
28
|
+
| `WORKFLOW` | Yes | Workflow type: "tdd", "trivial", etc. |
|
|
29
|
+
</arguments>
|
|
27
30
|
|
|
28
31
|
<gate>
|
|
29
32
|
## Handoff Checklist
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
- [ ] Session file exists with story context
|
|
35
|
+
- [ ] Acceptance criteria defined (count, don't mark)
|
|
36
|
+
- [ ] Feature branches created
|
|
37
|
+
- [ ] Jira story claimed (if applicable)
|
|
38
|
+
- [ ] Update Workflow Tracking section:
|
|
39
|
+
- `**Phase:**` → `{NEXT_PHASE}`
|
|
40
|
+
- `**Phase Started:**` → `{NOW}`
|
|
41
|
+
- Add Phase History row
|
|
42
|
+
- [ ] Report status summary
|
|
40
43
|
</gate>
|
|
41
44
|
|
|
42
45
|
## Phase Transition Update
|
|
@@ -58,51 +61,55 @@ Edit `## Workflow Tracking`:
|
|
|
58
61
|
|
|
59
62
|
**Duration:** Subtract SM Started from {NOW}, format as `Xm` or `Xh Ym`.
|
|
60
63
|
|
|
64
|
+
<output>
|
|
61
65
|
## Output Format
|
|
62
66
|
|
|
63
|
-
Return a `HANDOFF_RESULT` block
|
|
64
|
-
|
|
65
|
-
### Success Format
|
|
67
|
+
Return a `HANDOFF_RESULT` block:
|
|
66
68
|
|
|
69
|
+
### Success
|
|
67
70
|
```
|
|
68
71
|
HANDOFF_RESULT:
|
|
69
72
|
status: success
|
|
70
73
|
next_agent: {NEXT_AGENT}
|
|
71
74
|
next_phase: {NEXT_PHASE}
|
|
72
75
|
story_id: {STORY_ID}
|
|
73
|
-
summary: "
|
|
76
|
+
summary: "{what was done}"
|
|
77
|
+
|
|
78
|
+
next_steps:
|
|
79
|
+
- "Handoff complete. Run handoff-marker.sh as ABSOLUTE LAST ACTION."
|
|
80
|
+
- "Command: $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/core/handoff-marker.sh {next_agent}"
|
|
81
|
+
- "Output marker result verbatim, then EXIT. Nothing after."
|
|
74
82
|
```
|
|
75
83
|
|
|
76
84
|
### Example (SM → TEA)
|
|
77
|
-
|
|
78
85
|
```
|
|
79
86
|
HANDOFF_RESULT:
|
|
80
87
|
status: success
|
|
81
88
|
next_agent: tea
|
|
82
89
|
next_phase: red
|
|
83
90
|
story_id: MSSCI-12274
|
|
84
|
-
summary: "Session updated (setup → red), branch
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### Example (SM → Dev, trivial workflow)
|
|
91
|
+
summary: "Session updated (setup → red), branch verified, 7 AC defined"
|
|
88
92
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
next_phase: implement
|
|
94
|
-
story_id: 46-3
|
|
95
|
-
summary: "Session updated (setup → implement), branch feat/46-3-fix-typo verified"
|
|
93
|
+
next_steps:
|
|
94
|
+
- "Handoff complete. Run handoff-marker.sh as ABSOLUTE LAST ACTION."
|
|
95
|
+
- "Command: $CLAUDE_PROJECT_DIR/.pennyfarthing/scripts/core/handoff-marker.sh tea"
|
|
96
|
+
- "Output marker result verbatim, then EXIT. Nothing after."
|
|
96
97
|
```
|
|
97
98
|
|
|
98
|
-
###
|
|
99
|
-
|
|
99
|
+
### Blocked
|
|
100
100
|
```
|
|
101
101
|
HANDOFF_RESULT:
|
|
102
102
|
status: blocked
|
|
103
|
-
error: "{
|
|
103
|
+
error: "{description}"
|
|
104
104
|
fix: "{recommended action}"
|
|
105
|
+
failed_check: "{which gate check failed}"
|
|
106
|
+
|
|
107
|
+
next_steps:
|
|
108
|
+
- "Handoff blocked: {error}"
|
|
109
|
+
- "Required action: {fix}"
|
|
110
|
+
- "Do NOT run handoff-marker.sh. Resolve issue first."
|
|
105
111
|
```
|
|
112
|
+
</output>
|
|
106
113
|
|
|
107
114
|
---
|
|
108
115
|
|
|
@@ -5,10 +5,17 @@ tools: Bash, Read, Edit, Write
|
|
|
5
5
|
model: haiku
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
<arguments>
|
|
9
|
+
| Argument | Required | Description |
|
|
10
|
+
|----------|----------|-------------|
|
|
11
|
+
| `MODE` | Yes | `research` (scan backlog) or `setup` (execute story setup) |
|
|
12
|
+
| `STORY_ID` | setup | Story identifier, e.g., "31-10" |
|
|
13
|
+
| `JIRA_KEY` | setup | Jira issue key, e.g., "MSSCI-12345" |
|
|
14
|
+
| `REPOS` | setup | Repository name(s) |
|
|
15
|
+
| `SLUG` | setup | Branch slug, e.g., "fix-typo" |
|
|
16
|
+
| `WORKFLOW` | setup | Workflow type: "tdd", "trivial", etc. |
|
|
17
|
+
| `ASSIGNEE` | No | Jira assignee (defaults to current user) |
|
|
18
|
+
</arguments>
|
|
12
19
|
|
|
13
20
|
---
|
|
14
21
|
|
|
@@ -17,30 +24,45 @@ model: haiku
|
|
|
17
24
|
<gate>
|
|
18
25
|
## Research Steps
|
|
19
26
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
- [ ] Use `/sprint backlog` for initial backlog scan:
|
|
28
|
+
```bash
|
|
29
|
+
.pennyfarthing/scripts/core/run.sh sprint/available-stories.sh
|
|
30
|
+
```
|
|
31
|
+
- [ ] Use `/jira` skill to enrich with Jira status/assignee:
|
|
32
|
+
- `/jira search "project=MSSCI AND sprint in openSprints()"` - Get all sprint stories
|
|
33
|
+
- `/jira view {JIRA_KEY}` - Check individual story details
|
|
34
|
+
- [ ] Check context availability
|
|
35
|
+
- [ ] Check dependencies
|
|
36
|
+
- [ ] Output report with recommendations
|
|
30
37
|
</gate>
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
```markdown
|
|
35
|
-
## Sprint {N} Backlog Research
|
|
39
|
+
<output>
|
|
40
|
+
## Output Format (MODE: research)
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
| Story | Title | Points | Repos | Context |
|
|
39
|
-
|-------|-------|--------|-------|---------|
|
|
42
|
+
Return a `RESEARCH_RESULT` block:
|
|
40
43
|
|
|
41
|
-
### Recommended Next
|
|
42
|
-
**Story {ID}:** {TITLE} ({PTS} pts)
|
|
43
44
|
```
|
|
45
|
+
RESEARCH_RESULT:
|
|
46
|
+
status: success
|
|
47
|
+
sprint_number: {N}
|
|
48
|
+
available_count: {N}
|
|
49
|
+
stories:
|
|
50
|
+
- id: "{STORY_ID}"
|
|
51
|
+
title: "{title}"
|
|
52
|
+
points: {N}
|
|
53
|
+
repos: ["{repo}"]
|
|
54
|
+
context_ready: {true|false}
|
|
55
|
+
blocked_by: ["{dependency}"] or null
|
|
56
|
+
recommended:
|
|
57
|
+
id: "{STORY_ID}"
|
|
58
|
+
reason: "{why this story}"
|
|
59
|
+
|
|
60
|
+
next_steps:
|
|
61
|
+
- "Present stories to user for selection."
|
|
62
|
+
- "Recommended: {recommended.id} - {recommended.reason}"
|
|
63
|
+
- "On selection: Spawn sm-setup with MODE=setup, STORY_ID={selected}"
|
|
64
|
+
```
|
|
65
|
+
</output>
|
|
44
66
|
|
|
45
67
|
---
|
|
46
68
|
|
|
@@ -55,12 +77,12 @@ Other formats break Cyclist detection.
|
|
|
55
77
|
<gate>
|
|
56
78
|
## Setup Steps
|
|
57
79
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
80
|
+
- [ ] Verify epic has Jira key (auto-create if missing)
|
|
81
|
+
- [ ] Check workflow permissions (auto-prompt for missing)
|
|
82
|
+
- [ ] Claim story in Jira
|
|
83
|
+
- [ ] Write session file with Workflow Tracking section
|
|
84
|
+
- [ ] Create feature branch
|
|
85
|
+
- [ ] Update sprint YAML status
|
|
64
86
|
</gate>
|
|
65
87
|
|
|
66
88
|
## Step 1: Check Epic Jira
|
|
@@ -91,11 +113,13 @@ GRANTS=$(cat .claude/settings.local.json 2>/dev/null | jq '.permissions.grants /
|
|
|
91
113
|
**For each required permission:**
|
|
92
114
|
|
|
93
115
|
1. Check if a matching grant exists (same tool + scope)
|
|
94
|
-
2. If missing, prompt user
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
116
|
+
2. If missing, prompt user for permission:
|
|
117
|
+
- First output marker: `<!-- CYCLIST:QUESTION:yesno -->`
|
|
118
|
+
- Then use AskUserQuestion with the prompt:
|
|
119
|
+
```
|
|
120
|
+
"The {WORKFLOW} workflow requires {tool} access for: {reason}
|
|
121
|
+
Grant permission for {tool} with scope '{scope}'?"
|
|
122
|
+
```
|
|
99
123
|
3. If granted, add to `.claude/settings.local.json` under `permissions.grants[]`:
|
|
100
124
|
```json
|
|
101
125
|
{
|
|
@@ -154,21 +178,39 @@ cd $CLAUDE_PROJECT_DIR && git checkout develop && git pull && \
|
|
|
154
178
|
git checkout -b feat/{STORY_ID}-{SLUG}
|
|
155
179
|
```
|
|
156
180
|
|
|
157
|
-
|
|
181
|
+
<output>
|
|
182
|
+
## Output Format (MODE: setup)
|
|
158
183
|
|
|
159
|
-
|
|
160
|
-
## Setup Complete
|
|
184
|
+
Return a `SETUP_RESULT` block:
|
|
161
185
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
186
|
+
### Success
|
|
187
|
+
```
|
|
188
|
+
SETUP_RESULT:
|
|
189
|
+
status: success
|
|
190
|
+
story_id: "{STORY_ID}"
|
|
191
|
+
jira_key: "{JIRA_KEY}"
|
|
192
|
+
session_file: ".session/{STORY_ID}-session.md"
|
|
193
|
+
branch: "feat/{STORY_ID}-{SLUG}"
|
|
194
|
+
workflow: "{WORKFLOW}"
|
|
195
|
+
next_agent: "{tea|dev}"
|
|
196
|
+
|
|
197
|
+
next_steps:
|
|
198
|
+
- "Setup complete. Spawn sm-handoff to transition to {next_agent}."
|
|
199
|
+
- "Workflow '{workflow}' routes to: {next_agent}"
|
|
200
|
+
- "Session file ready at: {session_file}"
|
|
165
201
|
```
|
|
166
202
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
203
|
+
### Blocked
|
|
204
|
+
```
|
|
205
|
+
SETUP_RESULT:
|
|
206
|
+
status: blocked
|
|
207
|
+
error: "{description}"
|
|
208
|
+
fix: "{recommended action}"
|
|
209
|
+
stage: "{epic_jira|permissions|jira_claim|session|branch}"
|
|
210
|
+
|
|
211
|
+
next_steps:
|
|
212
|
+
- "Setup blocked at {stage}: {error}"
|
|
213
|
+
- "Required action: {fix}"
|
|
214
|
+
- "Do NOT proceed with handoff until resolved."
|
|
174
215
|
```
|
|
216
|
+
</output>
|