@codyswann/lisa 1.95.0 → 2.0.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/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +41 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/codex/agent-installer.d.ts +56 -0
- package/dist/codex/agent-installer.d.ts.map +1 -0
- package/dist/codex/agent-installer.js +201 -0
- package/dist/codex/agent-installer.js.map +1 -0
- package/dist/codex/agent-transformer.d.ts +53 -0
- package/dist/codex/agent-transformer.d.ts.map +1 -0
- package/dist/codex/agent-transformer.js +181 -0
- package/dist/codex/agent-transformer.js.map +1 -0
- package/dist/codex/agents-md-installer.d.ts +24 -0
- package/dist/codex/agents-md-installer.d.ts.map +1 -0
- package/dist/codex/agents-md-installer.js +63 -0
- package/dist/codex/agents-md-installer.js.map +1 -0
- package/dist/codex/hooks-installer.d.ts +24 -0
- package/dist/codex/hooks-installer.d.ts.map +1 -0
- package/dist/codex/hooks-installer.js +206 -0
- package/dist/codex/hooks-installer.js.map +1 -0
- package/dist/codex/hooks-merger.d.ts +82 -0
- package/dist/codex/hooks-merger.d.ts.map +1 -0
- package/dist/codex/hooks-merger.js +127 -0
- package/dist/codex/hooks-merger.js.map +1 -0
- package/dist/codex/manifest.d.ts +32 -0
- package/dist/codex/manifest.d.ts.map +1 -0
- package/dist/codex/manifest.js +86 -0
- package/dist/codex/manifest.js.map +1 -0
- package/dist/codex/settings-installer.d.ts +48 -0
- package/dist/codex/settings-installer.d.ts.map +1 -0
- package/dist/codex/settings-installer.js +276 -0
- package/dist/codex/settings-installer.js.map +1 -0
- package/dist/codex/skills-installer.d.ts +46 -0
- package/dist/codex/skills-installer.d.ts.map +1 -0
- package/dist/codex/skills-installer.js +344 -0
- package/dist/codex/skills-installer.js.map +1 -0
- package/dist/core/config.d.ts +19 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +13 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/lisa.d.ts +12 -0
- package/dist/core/lisa.d.ts.map +1 -1
- package/dist/core/lisa.js +48 -0
- package/dist/core/lisa.js.map +1 -1
- package/dist/core/project-config.d.ts +49 -0
- package/dist/core/project-config.d.ts.map +1 -0
- package/dist/core/project-config.js +119 -0
- package/dist/core/project-config.js.map +1 -0
- package/package.json +3 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/agents/jira-build-intake.md +58 -0
- package/plugins/lisa/agents/notion-prd-intake.md +57 -0
- package/plugins/lisa/commands/{plan/fix-linter-error.md → fix/linter-error.md} +1 -1
- package/plugins/lisa/commands/implement.md +6 -0
- package/plugins/{src/base/commands/plan/lower-code-complexity.md → lisa/commands/improve/code-complexity.md} +1 -1
- package/plugins/lisa/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +1 -1
- package/plugins/lisa/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +1 -1
- package/plugins/lisa/commands/{plan/improve-tests.md → improve/tests.md} +1 -1
- package/plugins/lisa/commands/plan.md +15 -3
- package/plugins/lisa/commands/product-walkthrough.md +7 -0
- package/plugins/{src/base/commands/plan/local-code-review.md → lisa/commands/review/local.md} +1 -1
- package/plugins/{src/base/skills/plan-fix-linter-error → lisa/skills/fix-linter-error}/SKILL.md +2 -2
- package/plugins/lisa/skills/{plan-execute → implement}/SKILL.md +1 -1
- package/plugins/lisa/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
- package/plugins/lisa/skills/{plan-reduce-max-lines → improve-max-lines}/SKILL.md +2 -2
- package/plugins/{src/base/skills/plan-reduce-max-lines-per-function → lisa/skills/improve-max-lines-per-function}/SKILL.md +2 -2
- package/plugins/lisa/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
- package/plugins/{src/base/skills/plan-improve-tests → lisa/skills/improve-tests}/SKILL.md +2 -2
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +134 -0
- package/plugins/lisa/skills/jira-create/SKILL.md +53 -30
- package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +107 -0
- package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +224 -0
- package/plugins/lisa/skills/jira-verify/SKILL.md +15 -91
- package/plugins/lisa/skills/jira-write-ticket/SKILL.md +20 -15
- package/plugins/lisa/skills/notion-prd-intake/SKILL.md +169 -0
- package/plugins/lisa/skills/notion-to-jira/SKILL.md +137 -95
- package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +137 -0
- package/plugins/lisa/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/lisa/skills/{plan-local-code-review → review-local}/SKILL.md +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/skills/jira-create/SKILL.md +60 -28
- package/plugins/lisa-expo/skills/jira-verify/SKILL.md +14 -34
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/skills/{plan-fix-linter-error → fix-linter-error}/SKILL.md +2 -2
- package/plugins/lisa-rails/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
- package/plugins/{src/rails/skills/plan-reduce-max-lines → lisa-rails/skills/improve-max-lines}/SKILL.md +2 -2
- package/plugins/{src/rails/skills/plan-reduce-max-lines-per-function → lisa-rails/skills/improve-max-lines-per-function}/SKILL.md +2 -2
- package/plugins/lisa-rails/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
- package/plugins/lisa-rails/skills/jira-create/SKILL.md +59 -28
- package/plugins/lisa-rails/skills/jira-verify/SKILL.md +13 -16
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/agents/jira-build-intake.md +58 -0
- package/plugins/src/base/agents/notion-prd-intake.md +57 -0
- package/plugins/src/base/commands/{plan/fix-linter-error.md → fix/linter-error.md} +1 -1
- package/plugins/src/base/commands/implement.md +6 -0
- package/plugins/{lisa/commands/plan/lower-code-complexity.md → src/base/commands/improve/code-complexity.md} +1 -1
- package/plugins/src/base/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +1 -1
- package/plugins/src/base/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +1 -1
- package/plugins/src/base/commands/{plan/improve-tests.md → improve/tests.md} +1 -1
- package/plugins/src/base/commands/plan.md +15 -3
- package/plugins/src/base/commands/product-walkthrough.md +7 -0
- package/plugins/{lisa/commands/plan/local-code-review.md → src/base/commands/review/local.md} +1 -1
- package/plugins/{lisa/skills/plan-fix-linter-error → src/base/skills/fix-linter-error}/SKILL.md +2 -2
- package/plugins/src/base/skills/{plan-execute → implement}/SKILL.md +1 -1
- package/plugins/src/base/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
- package/plugins/src/base/skills/{plan-reduce-max-lines → improve-max-lines}/SKILL.md +2 -2
- package/plugins/{lisa/skills/plan-reduce-max-lines-per-function → src/base/skills/improve-max-lines-per-function}/SKILL.md +2 -2
- package/plugins/src/base/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
- package/plugins/{lisa/skills/plan-improve-tests → src/base/skills/improve-tests}/SKILL.md +2 -2
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +134 -0
- package/plugins/src/base/skills/jira-create/SKILL.md +53 -30
- package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +107 -0
- package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +224 -0
- package/plugins/src/base/skills/jira-verify/SKILL.md +15 -91
- package/plugins/src/base/skills/jira-write-ticket/SKILL.md +20 -15
- package/plugins/src/base/skills/notion-prd-intake/SKILL.md +169 -0
- package/plugins/src/base/skills/notion-to-jira/SKILL.md +137 -95
- package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +137 -0
- package/plugins/src/base/skills/product-walkthrough/SKILL.md +129 -0
- package/plugins/src/base/skills/{plan-local-code-review → review-local}/SKILL.md +1 -1
- package/plugins/src/expo/skills/jira-create/SKILL.md +60 -28
- package/plugins/src/expo/skills/jira-verify/SKILL.md +14 -34
- package/plugins/src/rails/skills/{plan-fix-linter-error → fix-linter-error}/SKILL.md +2 -2
- package/plugins/src/rails/skills/{plan-lower-code-complexity → improve-code-complexity}/SKILL.md +2 -2
- package/plugins/{lisa-rails/skills/plan-reduce-max-lines → src/rails/skills/improve-max-lines}/SKILL.md +2 -2
- package/plugins/{lisa-rails/skills/plan-reduce-max-lines-per-function → src/rails/skills/improve-max-lines-per-function}/SKILL.md +2 -2
- package/plugins/src/rails/skills/{plan-add-test-coverage → improve-test-coverage}/SKILL.md +2 -2
- package/plugins/src/rails/skills/jira-create/SKILL.md +59 -28
- package/plugins/src/rails/skills/jira-verify/SKILL.md +13 -16
- package/plugins/lisa/commands/build.md +0 -12
- package/plugins/lisa/commands/fix.md +0 -12
- package/plugins/lisa/commands/improve.md +0 -18
- package/plugins/lisa/commands/investigate.md +0 -10
- package/plugins/lisa/commands/jira/add-journey.md +0 -7
- package/plugins/lisa/commands/jira/create.md +0 -7
- package/plugins/lisa/commands/jira/evidence.md +0 -7
- package/plugins/lisa/commands/jira/journey.md +0 -7
- package/plugins/lisa/commands/jira/read-ticket.md +0 -7
- package/plugins/lisa/commands/jira/sync.md +0 -7
- package/plugins/lisa/commands/jira/triage.md +0 -7
- package/plugins/lisa/commands/jira/verify.md +0 -7
- package/plugins/lisa/commands/jira/write-ticket.md +0 -7
- package/plugins/lisa/commands/plan/create.md +0 -8
- package/plugins/lisa/commands/plan/execute.md +0 -6
- package/plugins/lisa/commands/review/implementation.md +0 -7
- package/plugins/lisa/commands/review.md +0 -10
- package/plugins/lisa/commands/ship.md +0 -8
- package/plugins/lisa/commands/spec-conformance.md +0 -7
- package/plugins/lisa-expo/commands/jira/add-journey.md +0 -7
- package/plugins/lisa-expo/commands/jira/create.md +0 -7
- package/plugins/lisa-expo/commands/jira/evidence.md +0 -7
- package/plugins/lisa-expo/commands/jira/journey.md +0 -7
- package/plugins/lisa-expo/commands/jira/verify.md +0 -7
- package/plugins/lisa-rails/commands/jira/add-journey.md +0 -7
- package/plugins/lisa-rails/commands/jira/create.md +0 -7
- package/plugins/lisa-rails/commands/jira/evidence.md +0 -7
- package/plugins/lisa-rails/commands/jira/journey.md +0 -7
- package/plugins/lisa-rails/commands/jira/verify.md +0 -7
- package/plugins/src/base/commands/build.md +0 -12
- package/plugins/src/base/commands/fix.md +0 -12
- package/plugins/src/base/commands/improve.md +0 -18
- package/plugins/src/base/commands/investigate.md +0 -10
- package/plugins/src/base/commands/jira/add-journey.md +0 -7
- package/plugins/src/base/commands/jira/create.md +0 -7
- package/plugins/src/base/commands/jira/evidence.md +0 -7
- package/plugins/src/base/commands/jira/journey.md +0 -7
- package/plugins/src/base/commands/jira/read-ticket.md +0 -7
- package/plugins/src/base/commands/jira/sync.md +0 -7
- package/plugins/src/base/commands/jira/triage.md +0 -7
- package/plugins/src/base/commands/jira/verify.md +0 -7
- package/plugins/src/base/commands/jira/write-ticket.md +0 -7
- package/plugins/src/base/commands/plan/create.md +0 -8
- package/plugins/src/base/commands/plan/execute.md +0 -6
- package/plugins/src/base/commands/review/implementation.md +0 -7
- package/plugins/src/base/commands/review.md +0 -10
- package/plugins/src/base/commands/ship.md +0 -8
- package/plugins/src/base/commands/spec-conformance.md +0 -7
- package/plugins/src/expo/commands/jira/add-journey.md +0 -7
- package/plugins/src/expo/commands/jira/create.md +0 -7
- package/plugins/src/expo/commands/jira/evidence.md +0 -7
- package/plugins/src/expo/commands/jira/journey.md +0 -7
- package/plugins/src/expo/commands/jira/verify.md +0 -7
- package/plugins/src/rails/commands/jira/add-journey.md +0 -7
- package/plugins/src/rails/commands/jira/create.md +0 -7
- package/plugins/src/rails/commands/jira/evidence.md +0 -7
- package/plugins/src/rails/commands/jira/journey.md +0 -7
- package/plugins/src/rails/commands/jira/verify.md +0 -7
- /package/plugins/lisa/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
- /package/plugins/lisa-rails/commands/{plan/fix-linter-error.md → fix/linter-error.md} +0 -0
- /package/plugins/lisa-rails/commands/{plan/lower-code-complexity.md → improve/code-complexity.md} +0 -0
- /package/plugins/lisa-rails/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +0 -0
- /package/plugins/lisa-rails/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
- /package/plugins/lisa-rails/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +0 -0
- /package/plugins/src/base/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
- /package/plugins/src/rails/commands/{plan/fix-linter-error.md → fix/linter-error.md} +0 -0
- /package/plugins/src/rails/commands/{plan/lower-code-complexity.md → improve/code-complexity.md} +0 -0
- /package/plugins/src/rails/commands/{plan/reduce-max-lines-per-function.md → improve/max-lines-per-function.md} +0 -0
- /package/plugins/src/rails/commands/{plan/reduce-max-lines.md → improve/max-lines.md} +0 -0
- /package/plugins/src/rails/commands/{plan/add-test-coverage.md → improve/test-coverage.md} +0 -0
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: jira-validate-ticket
|
|
3
|
+
description: "Validates a proposed JIRA ticket spec (or an existing ticket) against the organizational quality gates without writing anything. Returns a structured PASS/FAIL report per gate with concrete remediation. This is the single source of truth for what makes a valid ticket — both the write path (jira-write-ticket runs it pre-write) and the dry-run path (notion-to-jira runs it during PRD intake) call this skill so the bar can never drift."
|
|
4
|
+
allowed-tools: ["Bash", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getIssueLinkTypes", "mcp__atlassian__getJiraProjectIssueTypesMetadata", "mcp__atlassian__getVisibleJiraProjects", "mcp__atlassian__getAccessibleAtlassianResources"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Validate JIRA Ticket: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
Run all organizational quality gates against a ticket spec OR an existing ticket. **This skill is read-only — it never writes to JIRA.** The output is a structured report consumed by callers (`jira-write-ticket` for pre-write gating, `notion-to-jira` for PRD dry-run, `jira-verify` for post-write checks).
|
|
10
|
+
|
|
11
|
+
## Input
|
|
12
|
+
|
|
13
|
+
`$ARGUMENTS` is one of:
|
|
14
|
+
|
|
15
|
+
1. **An existing ticket key** (e.g. `PROJ-1234`): fetch it and validate the live state. Use this for post-write checks.
|
|
16
|
+
2. **A proposed ticket spec** (YAML block, see schema below): validate as-is without touching JIRA. Use this for pre-write and dry-run checks.
|
|
17
|
+
|
|
18
|
+
### Spec schema
|
|
19
|
+
|
|
20
|
+
Specs are passed as a fenced YAML block. Required keys depend on `issue_type`.
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
issue_type: Story # Story | Task | Bug | Epic | Spike | Sub-task | Improvement
|
|
24
|
+
project_key: SE
|
|
25
|
+
summary: "[CU-1.2] Upload contract PDF from settings"
|
|
26
|
+
priority: Medium
|
|
27
|
+
parent_key: SE-1234 # Epic key for non-Bug/non-Epic; Story key for Sub-task
|
|
28
|
+
description: | # Full description text — every required section
|
|
29
|
+
h2. Context / Business Value
|
|
30
|
+
...
|
|
31
|
+
|
|
32
|
+
h2. Technical Approach
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
h2. Acceptance Criteria
|
|
36
|
+
# Given <precondition>
|
|
37
|
+
When <action>
|
|
38
|
+
Then <observable outcome>
|
|
39
|
+
|
|
40
|
+
h2. Out of Scope
|
|
41
|
+
...
|
|
42
|
+
|
|
43
|
+
h2. Target Backend Environment
|
|
44
|
+
dev
|
|
45
|
+
|
|
46
|
+
h2. Sign-in Required
|
|
47
|
+
Account: ...
|
|
48
|
+
|
|
49
|
+
h2. Repository
|
|
50
|
+
backend-api
|
|
51
|
+
|
|
52
|
+
h2. Validation Journey
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
# Behavioral flags — caller asserts these so the validator can pick the right gates
|
|
56
|
+
runtime_behavior_change: true # → requires Target Backend Environment + Validation Journey
|
|
57
|
+
authenticated_surface: true # → requires Sign-in Required
|
|
58
|
+
artifacts_attached: true # → requires Source Precedence section
|
|
59
|
+
links: [{ key: "PROJ-99", type: "is blocked by" }] # known issue links (may be empty)
|
|
60
|
+
remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If the caller passes only a ticket key, fetch the ticket via `mcp__atlassian__getJiraIssue`, derive the same fields from the fetched data, then run gates.
|
|
64
|
+
|
|
65
|
+
## Gates
|
|
66
|
+
|
|
67
|
+
Gates are grouped into **Specification** (spec-only checks, no JIRA lookups) and **Feasibility** (requires JIRA lookups). The dry-run path may opt to run Specification gates only; the write path runs both.
|
|
68
|
+
|
|
69
|
+
### Specification Gates
|
|
70
|
+
|
|
71
|
+
#### S1 — Required core fields
|
|
72
|
+
|
|
73
|
+
`project_key`, `issue_type`, `summary`, `priority`, `description` must all be present and non-empty.
|
|
74
|
+
|
|
75
|
+
#### S2 — Summary format
|
|
76
|
+
|
|
77
|
+
- Single line, ≤ 100 characters
|
|
78
|
+
- Imperative voice ("Add X", "Fix Y", not "Adding X" or "X is broken")
|
|
79
|
+
- Bug / Task / Sub-task summaries SHOULD start with a `[repo-name]` prefix when the project convention uses one
|
|
80
|
+
|
|
81
|
+
#### S3 — Description has all three audiences
|
|
82
|
+
|
|
83
|
+
Description text must include all of these sections (case-insensitive `h2.` headings):
|
|
84
|
+
- `Context / Business Value` — stakeholder-facing
|
|
85
|
+
- `Technical Approach` — developer-facing
|
|
86
|
+
- `Acceptance Criteria` — coding-assistant-facing
|
|
87
|
+
- `Out of Scope` — explicit non-coverage list
|
|
88
|
+
|
|
89
|
+
Missing any → FAIL with name of missing section.
|
|
90
|
+
|
|
91
|
+
#### S4 — Acceptance criteria in Gherkin
|
|
92
|
+
|
|
93
|
+
Applies when `issue_type ∈ {Story, Task, Bug, Sub-task, Improvement}`.
|
|
94
|
+
|
|
95
|
+
The `Acceptance Criteria` section must contain at least one criterion in `Given / When / Then` form. Reject prose-only criteria, "should work" language, or numbered lists without Given/When/Then verbs.
|
|
96
|
+
|
|
97
|
+
#### S5 — Bug-specific content
|
|
98
|
+
|
|
99
|
+
When `issue_type = Bug`, description must additionally include:
|
|
100
|
+
- Reproduction steps
|
|
101
|
+
- Expected vs. actual behavior
|
|
102
|
+
- Environment where reproduced
|
|
103
|
+
|
|
104
|
+
#### S6 — Spike-specific content
|
|
105
|
+
|
|
106
|
+
When `issue_type = Spike`, description must include:
|
|
107
|
+
- The question being answered
|
|
108
|
+
- Definition of done (decision doc / prototype / findings deliverable)
|
|
109
|
+
|
|
110
|
+
#### S7 — Epic parent declared
|
|
111
|
+
|
|
112
|
+
When `issue_type ∉ {Bug, Epic}`, `parent_key` must be set. (Validity of the key is checked in feasibility gates.)
|
|
113
|
+
|
|
114
|
+
#### S8 — Target Backend Environment
|
|
115
|
+
|
|
116
|
+
When `runtime_behavior_change = true`, description must contain `h2. Target Backend Environment` with one of `dev`, `staging`, `prod`. Skipped for doc-only / config-only / type-only / Epic.
|
|
117
|
+
|
|
118
|
+
#### S9 — Sign-in Required
|
|
119
|
+
|
|
120
|
+
When `authenticated_surface = true`, description must contain `h2. Sign-in Required` naming the account/role and credential source (1Password item, env var, seeded fixture).
|
|
121
|
+
|
|
122
|
+
If the spec doesn't set `authenticated_surface`, infer it: scan the description and AC for sign-in / login / "as a {role} user" / authenticated route signals. If signals present and no `Sign-in Required` section: FAIL.
|
|
123
|
+
|
|
124
|
+
#### S10 — Repository section, single-repo scope
|
|
125
|
+
|
|
126
|
+
When `issue_type ∈ {Bug, Task, Sub-task}`, description must contain `h2. Repository` naming exactly one repo. Multiple repos OR cross-repo references in AC: FAIL with recommendation to split.
|
|
127
|
+
|
|
128
|
+
Story / Epic / Spike / Improvement: skipped (may span repos).
|
|
129
|
+
|
|
130
|
+
#### S11 — Validation Journey present
|
|
131
|
+
|
|
132
|
+
When `runtime_behavior_change = true`, description must contain `h2. Validation Journey`. Skipped for doc-only / config-only / type-only / Epic.
|
|
133
|
+
|
|
134
|
+
The caller controls the strictness by passing `journey_followup: "auto"` or `journey_followup: "none"` in the spec:
|
|
135
|
+
- `auto` (default): if the section is absent, return `FAIL` with remediation `"Invoke jira-add-journey to append the section after create"`. Callers like `jira-write-ticket` know to chain `jira-add-journey` automatically, so this counts as a fixable failure they can resolve in-line — they re-run validation after appending.
|
|
136
|
+
- `none`: missing section is a `FAIL` that the caller will not auto-fix, so the verdict gates progress (used by dry-run paths like `notion-to-jira` PRD intake, where there's no agent standing by to add the journey).
|
|
137
|
+
|
|
138
|
+
Either way the gate emits `FAIL`, not a third state. Strictness is the caller's policy, not the validator's.
|
|
139
|
+
|
|
140
|
+
#### S12 — Source Precedence (when artifacts attached)
|
|
141
|
+
|
|
142
|
+
When `artifacts_attached = true`, description must include source-precedence guidance covering: business rules → PRD body, visual treatment → mocks, flow → prototypes, API/data → data artifacts. Cross-axis conflicts surfaced under `## Open Questions`.
|
|
143
|
+
|
|
144
|
+
Accept either placement — both are valid per `jira-source-artifacts`:
|
|
145
|
+
- A dedicated `## Source Precedence` (or `h2. Source Precedence`) subsection, OR
|
|
146
|
+
- A "Source Precedence" / "source precedence" / "authoritative source" paragraph under `Technical Approach` that covers the four axes above.
|
|
147
|
+
|
|
148
|
+
Detect by scanning for the phrase `Source Precedence` (case-insensitive) anywhere in the description, AND verifying the four axes (business rules, visual, flow, data) are each named. Missing the phrase OR missing one or more axes: FAIL with a remediation that names the missing axes.
|
|
149
|
+
|
|
150
|
+
#### S13 — Relationship Search documented
|
|
151
|
+
|
|
152
|
+
The ticket must EITHER have at least one issue link in `links`, OR the description / a comment must contain a `## Relationship Search` block listing the git history queries and JQL queries that were run with their outcomes ("Searched git history for `<keywords>` and JQL for component=`X`; no related work found.").
|
|
153
|
+
|
|
154
|
+
A ticket with zero links and no documented search: FAIL.
|
|
155
|
+
|
|
156
|
+
### Feasibility Gates (require JIRA lookups; skip in dry-run if requested)
|
|
157
|
+
|
|
158
|
+
#### F1 — Issue type valid in project
|
|
159
|
+
|
|
160
|
+
Call `mcp__atlassian__getJiraProjectIssueTypesMetadata` and confirm `issue_type` exists in `project_key`.
|
|
161
|
+
|
|
162
|
+
#### F2 — Epic parent exists and is an Epic
|
|
163
|
+
|
|
164
|
+
When `parent_key` is set for non-Sub-task: fetch via `mcp__atlassian__getJiraIssue`, confirm the issue type is `Epic`. For Sub-task, confirm the parent is a non-Sub-task in the same project.
|
|
165
|
+
|
|
166
|
+
#### F3 — Linked tickets exist
|
|
167
|
+
|
|
168
|
+
For each entry in `links`, call `mcp__atlassian__getJiraIssue` to confirm the key resolves. Flag broken keys.
|
|
169
|
+
|
|
170
|
+
#### F4 — Required custom fields populated
|
|
171
|
+
|
|
172
|
+
`mcp__atlassian__getJiraProjectIssueTypesMetadata` returns required custom fields for the issue type. Any required custom field not provided in the spec: FAIL.
|
|
173
|
+
|
|
174
|
+
## Execution
|
|
175
|
+
|
|
176
|
+
1. Parse `$ARGUMENTS`. If it's a ticket key, fetch the ticket and derive the spec from the fetched fields. Otherwise parse the YAML spec.
|
|
177
|
+
2. Resolve cloud ID via `mcp__atlassian__getAccessibleAtlassianResources` if any feasibility gate will run.
|
|
178
|
+
3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
|
|
179
|
+
4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
|
|
180
|
+
5. Emit the report below.
|
|
181
|
+
|
|
182
|
+
## Output
|
|
183
|
+
|
|
184
|
+
Output is a single fenced text block. Callers parse it; do not add free-form prose around it.
|
|
185
|
+
|
|
186
|
+
```text
|
|
187
|
+
## jira-validate-ticket: <TICKET-KEY-or-SUMMARY>
|
|
188
|
+
|
|
189
|
+
### Specification Gates
|
|
190
|
+
- [PASS|FAIL|N/A] S1 Required core fields — <one-line reason>
|
|
191
|
+
- [PASS|FAIL|N/A] S2 Summary format — <one-line reason>
|
|
192
|
+
- [PASS|FAIL|N/A] S3 Description three audiences — <one-line reason>
|
|
193
|
+
- [PASS|FAIL|N/A] S4 Acceptance criteria in Gherkin — <one-line reason>
|
|
194
|
+
- [PASS|FAIL|N/A] S5 Bug-specific content — <one-line reason>
|
|
195
|
+
- [PASS|FAIL|N/A] S6 Spike-specific content — <one-line reason>
|
|
196
|
+
- [PASS|FAIL|N/A] S7 Epic parent declared — <one-line reason>
|
|
197
|
+
- [PASS|FAIL|N/A] S8 Target Backend Environment — <one-line reason>
|
|
198
|
+
- [PASS|FAIL|N/A] S9 Sign-in Required — <one-line reason>
|
|
199
|
+
- [PASS|FAIL|N/A] S10 Single-repo scope — <one-line reason>
|
|
200
|
+
- [PASS|FAIL|N/A] S11 Validation Journey — <one-line reason>
|
|
201
|
+
- [PASS|FAIL|N/A] S12 Source Precedence — <one-line reason>
|
|
202
|
+
- [PASS|FAIL|N/A] S13 Relationship Search — <one-line reason>
|
|
203
|
+
|
|
204
|
+
### Feasibility Gates (omit this section when --spec-only)
|
|
205
|
+
- [PASS|FAIL|N/A] F1 Issue type valid in project — <one-line reason>
|
|
206
|
+
- [PASS|FAIL|N/A] F2 Epic parent exists and is an Epic — <one-line reason>
|
|
207
|
+
- [PASS|FAIL|N/A] F3 Linked tickets exist — <one-line reason>
|
|
208
|
+
- [PASS|FAIL|N/A] F4 Required custom fields populated — <one-line reason>
|
|
209
|
+
|
|
210
|
+
### Verdict: PASS | FAIL
|
|
211
|
+
### Failures: <count>
|
|
212
|
+
### Remediation
|
|
213
|
+
- <gate-id>: <concrete fix the caller can apply or surface to the user>
|
|
214
|
+
- <gate-id>: <concrete fix>
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The verdict is `PASS` if and only if every applicable gate is `PASS`. Any `FAIL` makes the verdict `FAIL`. `N/A` does not affect the verdict.
|
|
218
|
+
|
|
219
|
+
## Rules
|
|
220
|
+
|
|
221
|
+
- Never write to JIRA. The `allowed-tools` list intentionally excludes `createJiraIssue`, `editJiraIssue`, `createIssueLink`, `addCommentToJiraIssue`.
|
|
222
|
+
- Never auto-fix the spec. This skill reports gaps; callers decide what to do (block, ask the human, regenerate the spec).
|
|
223
|
+
- Never silently skip a gate. If a gate genuinely doesn't apply, return `N/A` with the reason; never omit it.
|
|
224
|
+
- The remediation lines must be concrete and actionable — the dry-run path turns each one into a Notion comment, so vague guidance is useless.
|
|
@@ -1,104 +1,28 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jira-verify
|
|
3
|
-
description: This skill should be used when verifying that a JIRA ticket meets organizational standards for epic relationships and description quality. It
|
|
4
|
-
allowed-tools: ["
|
|
3
|
+
description: This skill should be used when verifying that a JIRA ticket meets organizational standards for epic relationships and description quality. It fetches the live ticket and delegates the gate checks to jira-validate-ticket so the bar matches what jira-write-ticket enforces pre-write.
|
|
4
|
+
allowed-tools: ["Skill", "mcp__atlassian__getJiraIssue", "mcp__atlassian__getAccessibleAtlassianResources"]
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Verify JIRA Ticket: $ARGUMENTS
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Verify that the existing JIRA ticket `$ARGUMENTS` meets organizational standards. This skill is a thin post-write wrapper around `jira-validate-ticket`: it fetches the live ticket and asks `jira-validate-ticket` to run the gates against the fetched state.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
This indirection exists so the gate definitions live in exactly one place (`jira-validate-ticket`). When the bar changes, change it there — `jira-verify`, `jira-write-ticket` (Phase 5.5 pre-write), and `notion-to-jira` (PRD dry-run) all pick it up.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Process
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
1. Resolve cloud ID via `mcp__atlassian__getAccessibleAtlassianResources`.
|
|
16
|
+
2. Fetch the ticket via `mcp__atlassian__getJiraIssue` for `$ARGUMENTS`. Pull issue type, summary, description, parent, links, labels, components, and any custom fields needed.
|
|
17
|
+
3. Invoke `jira-validate-ticket` and pass the ticket key. The validator fetches its own copy if needed and runs every gate (Specification + Feasibility) against the live state.
|
|
18
|
+
4. Surface the validator's report verbatim to the caller.
|
|
16
19
|
|
|
17
|
-
|
|
20
|
+
## Output
|
|
18
21
|
|
|
19
|
-
|
|
22
|
+
Pass through `jira-validate-ticket`'s structured output unchanged. Do not summarize or paraphrase — downstream callers (e.g. `jira-agent`'s pre-flight gate) parse the gate lines.
|
|
20
23
|
|
|
21
|
-
|
|
24
|
+
## Notes
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
### 3. Validation Journey
|
|
28
|
-
|
|
29
|
-
**Rule**: Tickets that change runtime behavior MUST include a Validation Journey section.
|
|
30
|
-
|
|
31
|
-
Check by running:
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
python3 .claude/skills/jira-journey/scripts/parse-plan.py <TICKET_ID> 2>&1
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
- If the parser returns steps: PASS
|
|
38
|
-
- If the parser fails with "No 'Validation Journey' section found": FAIL — recommend using `/jira-add-journey <TICKET_ID>` to add one
|
|
39
|
-
|
|
40
|
-
This check is skipped for:
|
|
41
|
-
- Documentation-only tickets
|
|
42
|
-
- Config-only tickets (env vars, CI/CD, feature flags)
|
|
43
|
-
- Type-definition-only tickets (no runtime effect)
|
|
44
|
-
- Epic-level tickets (journeys belong on child stories/tasks)
|
|
45
|
-
|
|
46
|
-
### 4. Target Backend Environment
|
|
47
|
-
|
|
48
|
-
**Rule**: Tickets that change runtime behavior MUST name a target backend environment in the description.
|
|
49
|
-
|
|
50
|
-
Look for an `h2. Target Backend Environment` section (or equivalent named callout) containing one of `dev`, `staging`, or `prod`. The check is skipped for the same exclusions as the Validation Journey (doc-only, config-only, type-only, Epic).
|
|
51
|
-
|
|
52
|
-
- If present and valid: PASS
|
|
53
|
-
- If missing or unparseable: FAIL — recommend adding the section. QA/product report against a deployed env; the implementer needs to know which backend to point local at before CI/CD.
|
|
54
|
-
|
|
55
|
-
### 5. Sign-in Credentials (Conditional)
|
|
56
|
-
|
|
57
|
-
**Rule**: If the ticket touches an authenticated surface, the description MUST name the account/role to sign in as and where to get credentials.
|
|
58
|
-
|
|
59
|
-
A surface is "authenticated" if any of these signals are present in the description, acceptance criteria, or Validation Journey:
|
|
60
|
-
- Verbs like "log in", "sign in", "as a {role} user", "authenticated"
|
|
61
|
-
- Routes/screens that require auth in this product
|
|
62
|
-
- Roles named (admin, customer, partner, etc.)
|
|
63
|
-
|
|
64
|
-
If those signals are present, look for an `h2. Sign-in Required` section naming an account or credential source.
|
|
65
|
-
|
|
66
|
-
- If signals absent: PASS (sign-in not required)
|
|
67
|
-
- If signals present and section present: PASS
|
|
68
|
-
- If signals present and section missing: FAIL — recommend adding it. Implementers must not have to guess which account to use.
|
|
69
|
-
|
|
70
|
-
### 6. Single-Repo Scope (Bug / Task / Sub-task)
|
|
71
|
-
|
|
72
|
-
**Rule**: Bug, Task, and Sub-task tickets MUST cover one repo. Epic, Spike, and Story may span multiple repos.
|
|
73
|
-
|
|
74
|
-
Check by inspecting the description's `h2. Repository` section (or equivalent) and any explicit cross-repo references in the description / acceptance criteria.
|
|
75
|
-
|
|
76
|
-
- Bug / Task / Sub-task that names exactly one repo: PASS
|
|
77
|
-
- Bug / Task / Sub-task that names multiple repos OR has acceptance criteria spanning repos: FAIL — recommend splitting into per-repo tickets under a parent Story/Epic.
|
|
78
|
-
- Other types: skipped.
|
|
79
|
-
|
|
80
|
-
### 7. Relationship Discovery
|
|
81
|
-
|
|
82
|
-
**Rule**: Every ticket MUST have either at least one issue link OR a documented relationship search showing none was found.
|
|
83
|
-
|
|
84
|
-
- If the ticket has any issue link (`blocks`, `is blocked by`, `relates to`, `duplicates`, `clones`): PASS
|
|
85
|
-
- If no links but the description (or a comment) contains a `## Relationship Search` block listing the git and JQL queries that were run with their outcomes: PASS
|
|
86
|
-
- If no links and no documented search: FAIL — recommend running `/jira-write-ticket` (or its discovery phase) to capture the search.
|
|
87
|
-
|
|
88
|
-
## Execute Verification
|
|
89
|
-
|
|
90
|
-
Retrieve ticket details, run all checks, and produce a single output block. For each FAIL include the specific remediation. The caller (typically `jira-agent`) uses the FAIL list to decide whether to gate work — see the agent's pre-flight gate.
|
|
91
|
-
|
|
92
|
-
```text
|
|
93
|
-
## jira-verify: <TICKET-KEY>
|
|
94
|
-
- Epic parent: PASS | FAIL — <reason>
|
|
95
|
-
- Description quality: PASS | FAIL — <reason>
|
|
96
|
-
- Validation Journey: PASS | FAIL | N/A — <reason>
|
|
97
|
-
- Target backend environment: PASS | FAIL | N/A — <reason>
|
|
98
|
-
- Sign-in credentials: PASS | FAIL | N/A — <reason>
|
|
99
|
-
- Single-repo scope: PASS | FAIL | N/A — <reason>
|
|
100
|
-
- Relationship discovery: PASS | FAIL — <reason>
|
|
101
|
-
|
|
102
|
-
## Verdict: PASS | FAIL
|
|
103
|
-
## Missing requirements: [list of FAILed checks, or "none"]
|
|
104
|
-
```
|
|
26
|
+
- This skill is read-only. It never edits the ticket, posts comments, or changes status.
|
|
27
|
+
- If a gate fails, the recommendation is part of the validator's report; surface it as-is.
|
|
28
|
+
- Validation Journey checks (S11) historically required a parser script (`parse-plan.py`); the parser logic now lives inside `jira-validate-ticket` so this skill no longer shells out to it.
|
|
@@ -170,28 +170,19 @@ Identify and attach:
|
|
|
170
170
|
- Confluence pages (design docs, RFCs, runbooks)
|
|
171
171
|
- Dashboards (Grafana, Datadog, Sentry issue)
|
|
172
172
|
- Incident tickets (PagerDuty, Statuspage)
|
|
173
|
-
- **Source artifacts from the originating PRD / parent epic**:
|
|
174
|
-
|
|
175
|
-
Domain disambiguation (applied on inheritance):
|
|
176
|
-
- Figma URL with `/proto/` in path or `starting-point-node-id=` in query → `ux-flow`; otherwise `ui-design`.
|
|
177
|
-
- Lovable output → always `ux-flow`; its code/styling is not authoritative.
|
|
178
|
-
- Loom / annotated screenshot → `ux-flow`.
|
|
179
|
-
- Bare screenshot → `ui-design`.
|
|
173
|
+
- **Source artifacts from the originating PRD / parent epic**: classify and inherit per the rules in `jira-source-artifacts` (invoke that skill if you haven't loaded the rules in this session). The short version: enumerate the parent epic's remote links and inherit the ones whose domain matches this ticket's scope (UI → `ui-design` + `ux-flow`; backend → `data`; infra → `ops`; always inherit `reference`). Never assume a developer will walk up to the epic to find design context — attach it here.
|
|
180
174
|
|
|
181
175
|
If the ticket was generated from a PRD (by `notion-to-jira` or similar) and the parent epic has no source artifacts, surface that as a smell and ask whether artifacts were missed during extraction before proceeding.
|
|
182
176
|
|
|
183
177
|
### 4d. Source Precedence (must appear on the ticket)
|
|
184
178
|
|
|
185
|
-
When a ticket carries both design artifacts and a description,
|
|
179
|
+
Source precedence rules and cross-axis conflict handling are defined in `jira-source-artifacts` §3 and §4. When a ticket carries both design artifacts and a description, record the precedence explicitly in the ticket description (under Technical Approach or a dedicated `## Source Precedence` subsection) so the implementer doesn't silently reconcile conflicts. Cross-axis conflicts go under `## Open Questions` as BLOCKER items.
|
|
186
180
|
|
|
187
|
-
-
|
|
188
|
-
- **Visual treatment** (layout, spacing, typography, color, iconography) → **mocks (`ui-design`)** win.
|
|
189
|
-
- **Flow and interaction** (navigation, transitions, state changes, timing, empty/error/loading states) → **prototypes (`ux-flow`)** win.
|
|
190
|
-
- **API / data shape** → **`data` artifacts** win.
|
|
181
|
+
For UI-touching tickets, include the existing-component reuse expectation per `jira-source-artifacts` §7.
|
|
191
182
|
|
|
192
|
-
|
|
183
|
+
### 4e. Live Product Walkthrough Findings (UI-touching tickets)
|
|
193
184
|
|
|
194
|
-
|
|
185
|
+
If the ticket modifies an existing user-facing surface, a `product-walkthrough` should already have been run upstream (by `notion-to-jira` Phase 2b or `jira-create`). Inherit its findings under a `## Current Product` subsection in the ticket description so the implementer sees what's shipped today before changing it. If the upstream skill skipped the walkthrough but this ticket clearly modifies an existing surface, invoke `product-walkthrough` here before proceeding.
|
|
195
186
|
|
|
196
187
|
Use Jira's web UI or `mcp__atlassian__editJiraIssue` to set the `Development` field / remote links where supported.
|
|
197
188
|
|
|
@@ -207,6 +198,19 @@ Before create/update, verify each field is populated where applicable:
|
|
|
207
198
|
- Sprint: only if actively sprinting this work
|
|
208
199
|
- Assignee: leave unset if unknown rather than auto-assigning
|
|
209
200
|
|
|
201
|
+
## Phase 5.5 — Validate (Pre-write Gate)
|
|
202
|
+
|
|
203
|
+
Before any write, invoke `jira-validate-ticket` with the full proposed spec assembled from Phases 2 / 3 / 4 / 5. Pass it as a YAML block per the `jira-validate-ticket` schema, including `runtime_behavior_change`, `authenticated_surface`, and `artifacts_attached` flags so the right gates run.
|
|
204
|
+
|
|
205
|
+
The validator is the **single source of truth** for what makes a valid ticket. The same gates are used by `notion-to-jira` dry-run, by `jira-verify` post-write, and here. Do not re-implement gate logic in this skill — if a gate needs to change, change `jira-validate-ticket` so every caller benefits.
|
|
206
|
+
|
|
207
|
+
If the validator reports `FAIL`:
|
|
208
|
+
- Surface the failure list and the per-gate remediation to the user.
|
|
209
|
+
- Do NOT proceed to Phase 6. Fix the spec (or stop and ask the human) and re-run validation.
|
|
210
|
+
- Never call `mcp__atlassian__createJiraIssue` or `mcp__atlassian__editJiraIssue` while the validator's verdict is FAIL.
|
|
211
|
+
|
|
212
|
+
If the validator reports `PASS`, continue to Phase 6.
|
|
213
|
+
|
|
210
214
|
## Phase 6 — Create or Update
|
|
211
215
|
|
|
212
216
|
### CREATE
|
|
@@ -225,7 +229,7 @@ Before create/update, verify each field is populated where applicable:
|
|
|
225
229
|
|
|
226
230
|
## Phase 7 — Verify
|
|
227
231
|
|
|
228
|
-
Call the `jira-verify` skill on the resulting ticket. If it reports failures, fix them before returning. Do not report success on a ticket that fails verify.
|
|
232
|
+
Call the `jira-verify` skill on the resulting ticket. `jira-verify` fetches the live ticket and runs `jira-validate-ticket` against it — same gates as Phase 5.5, but applied to what JIRA actually stored (catches anything dropped or reformatted on write). If it reports failures, fix them before returning. Do not report success on a ticket that fails verify.
|
|
229
233
|
|
|
230
234
|
## Phase 8 — Announce
|
|
231
235
|
|
|
@@ -246,3 +250,4 @@ Skip this step only on UPDATE when no material change was made.
|
|
|
246
250
|
- Never invent custom field values. If the project requires a field you don't have, stop and ask.
|
|
247
251
|
- Never overwrite a description without reading the current version first.
|
|
248
252
|
- All writes go through this skill so best practices are enforced uniformly. Downstream skills (e.g. `jira-create`) should delegate here rather than calling the MCP write tools directly.
|
|
253
|
+
- The gate logic (what makes a valid ticket) lives in `jira-validate-ticket`, NOT in this skill. This skill calls the validator at Phase 5.5 (pre-write) and Phase 7 (via `jira-verify` post-write). When a gate needs to change, change it in `jira-validate-ticket` — every caller (write path, dry-run path, post-write verify) picks it up automatically.
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: notion-prd-intake
|
|
3
|
+
description: "Scans a Notion PRD database for pages with Status=Ready and runs each one through the dry-run validation pipeline. PRDs that pass every gate get tickets written and Status=Ticketed; PRDs that fail get clarifying-question comments and Status=Blocked. The skill is the runtime for the Ready → In Review → Blocked|Ticketed lifecycle. Composes existing skills (notion-to-jira, jira-validate-ticket, jira-source-artifacts, product-walkthrough); does not reimplement their logic."
|
|
4
|
+
allowed-tools: ["Skill", "Bash", "mcp__claude_ai_Notion__notion-fetch", "mcp__claude_ai_Notion__notion-search", "mcp__claude_ai_Notion__notion-update-page", "mcp__claude_ai_Notion__notion-create-comment", "mcp__atlassian__getAccessibleAtlassianResources"]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Notion PRD Intake: $ARGUMENTS
|
|
8
|
+
|
|
9
|
+
`$ARGUMENTS` is a Notion database URL (or bare database ID) — for example:
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
https://www.notion.so/geminisports/28fd00244d7d47c5866876f7de48c0fe?v=34eba63a2800815891a3000c643f0ea8
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Run one intake cycle against that database. Each PRD with `Status = Ready` is claimed, validated, and routed to either `Blocked` (with clarifying comments) or `Ticketed` (with JIRA tickets created).
|
|
16
|
+
|
|
17
|
+
## Lifecycle assumed
|
|
18
|
+
|
|
19
|
+
The PRD database has a `Status` property whose value drives this skill:
|
|
20
|
+
|
|
21
|
+
```text
|
|
22
|
+
Draft → Ready → In Review → Blocked | Ticketed → Shipped
|
|
23
|
+
(product) (us) (us) (product)
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This skill ONLY transitions `Ready → In Review`, then `In Review → Blocked` or `In Review → Ticketed`. Never touches `Draft` or `Shipped`.
|
|
27
|
+
|
|
28
|
+
## Phases
|
|
29
|
+
|
|
30
|
+
### Phase 1 — Resolve the database
|
|
31
|
+
|
|
32
|
+
1. Parse `$ARGUMENTS`:
|
|
33
|
+
- Full URL: extract the database ID from the path segment (the 32-hex-char ID after the last `/`, before `?`). Strip dashes if present. Ignore the `?v=...` view ID — we query the data source directly.
|
|
34
|
+
- Bare ID: use as-is.
|
|
35
|
+
2. Call `mcp__claude_ai_Notion__notion-fetch` on the database ID. Capture:
|
|
36
|
+
- The data source ID from `<data-source url="collection://...">` — needed for queries.
|
|
37
|
+
- Confirm the schema includes a `Status` property of type `select` (or `status`) with the expected option names (`Ready`, `In Review`, `Blocked`, `Ticketed` at minimum). If any are missing, stop and report — the database is misconfigured.
|
|
38
|
+
3. Resolve Atlassian cloud ID via `mcp__atlassian__getAccessibleAtlassianResources` (downstream skills need it).
|
|
39
|
+
|
|
40
|
+
### Phase 2 — Find Ready PRDs
|
|
41
|
+
|
|
42
|
+
Query the data source for pages where `Status = Ready`. Use `mcp__claude_ai_Notion__notion-search` with `data_source_url: collection://<data-source-id>` and a query that scopes to that collection. The search supports semantic queries; for an exact-status filter, scan the returned page list and keep only those whose `Status` property equals `Ready` (re-fetch each page if the search results don't expose properties).
|
|
43
|
+
|
|
44
|
+
If the result set is empty, stop and report `"No PRDs with Status=Ready. Nothing to do."` Exit cleanly — this is the common idle case for a scheduled run.
|
|
45
|
+
|
|
46
|
+
### Phase 3 — Process each Ready PRD
|
|
47
|
+
|
|
48
|
+
For each PRD page (process serially to keep status transitions auditable):
|
|
49
|
+
|
|
50
|
+
#### 3a. Claim
|
|
51
|
+
|
|
52
|
+
Set `Status = In Review` via `mcp__claude_ai_Notion__notion-update-page` with `command: update_properties`, `properties: { "Status": "In Review" }`. This is the idempotency lock — if a second cycle starts while this one is mid-flight, the second skip-filter (`Status = Ready`) won't see this PRD.
|
|
53
|
+
|
|
54
|
+
If the update fails (permission error, race), log it and skip this PRD. Do not proceed to validation on a PRD you didn't successfully claim.
|
|
55
|
+
|
|
56
|
+
#### 3b. Dry-run validation
|
|
57
|
+
|
|
58
|
+
Invoke the `notion-to-jira` skill with `dry_run: true` and the PRD's URL. The skill returns a structured report containing:
|
|
59
|
+
- The planned ticket hierarchy
|
|
60
|
+
- Per-ticket validation verdicts and remediation
|
|
61
|
+
- An overall PASS / FAIL verdict
|
|
62
|
+
- A failure count
|
|
63
|
+
|
|
64
|
+
This call also indirectly invokes `jira-source-artifacts` (artifact extraction + classification) and `product-walkthrough` (when the PRD touches existing user-facing surfaces). All gate logic lives in `jira-validate-ticket`, which `notion-to-jira` calls per ticket.
|
|
65
|
+
|
|
66
|
+
#### 3c. Branch on the verdict
|
|
67
|
+
|
|
68
|
+
**If `PASS`** (every planned ticket passed every applicable gate):
|
|
69
|
+
|
|
70
|
+
1. Re-invoke `notion-to-jira` with `dry_run: false` to actually write the tickets. This re-runs Phases 1-5 and runs the preservation gate (Phase 5.5).
|
|
71
|
+
2. Capture the created ticket keys from the skill's output.
|
|
72
|
+
3. Post a Notion comment on the PRD via `mcp__claude_ai_Notion__notion-create-comment` listing the created tickets (epic, stories, sub-tasks) with their JIRA URLs. Lead with: `"Ticketed by Claude. Created N JIRA issues — see below. Move Status to Shipped after the work is delivered."`
|
|
73
|
+
4. Set `Status = Ticketed` via `notion-update-page`.
|
|
74
|
+
5. **Run Phase 3e (coverage audit)** before considering this PRD done.
|
|
75
|
+
|
|
76
|
+
#### 3e. Coverage audit (mandatory after Ticketed)
|
|
77
|
+
|
|
78
|
+
Per-ticket gates prove each ticket is well-formed; they do NOT prove the *set* of created tickets covers the *whole* PRD. Silent drops happen — invoke the `prd-ticket-coverage` skill to catch them.
|
|
79
|
+
|
|
80
|
+
1. Invoke `prd-ticket-coverage` with `<PRD URL> tickets=[<created ticket keys from step 2 above>]`.
|
|
81
|
+
2. Read the verdict:
|
|
82
|
+
|
|
83
|
+
| Verdict | Action |
|
|
84
|
+
|---------|--------|
|
|
85
|
+
| `COMPLETE` | Done. Leave `Status = Ticketed`. Move to next PRD. |
|
|
86
|
+
| `COMPLETE_WITH_SCOPE_CREEP` | Post an advisory Notion comment naming the scope-creep tickets (so product can decide whether to close them as out-of-scope). Leave `Status = Ticketed`. |
|
|
87
|
+
| `GAPS_FOUND` | The created ticket set is incomplete. (a) For each gap, post a Notion comment naming the missing PRD item and where it appears in the PRD, with the suggested fix from the audit report. (b) Post one summary comment listing the tickets that *were* successfully created (so product knows what to keep vs. what to extend). (c) Transition `Status` from `Ticketed` back to `Blocked` via `notion-update-page`. |
|
|
88
|
+
| `NO_TICKETS_FOUND` | Should not happen if step 2 succeeded. If it does, log it as an Error in the cycle summary and leave `Status = Ticketed` with a comment flagging the audit failure for human review. |
|
|
89
|
+
|
|
90
|
+
3. The created tickets remain in JIRA regardless of the verdict — they are valid in their own right (they passed `jira-validate-ticket`). The audit only tells us whether *more* are needed.
|
|
91
|
+
|
|
92
|
+
The audit's report should be summarized in the cycle summary alongside the per-PRD outcome (e.g., `Ticketed (coverage: COMPLETE)` or `Blocked (coverage gaps: 3)`).
|
|
93
|
+
|
|
94
|
+
**If `FAIL`** (one or more planned tickets failed one or more gates):
|
|
95
|
+
|
|
96
|
+
1. Group the failures by planned ticket.
|
|
97
|
+
2. For each failed ticket, post a Notion comment via `notion-create-comment` with this format:
|
|
98
|
+
|
|
99
|
+
```text
|
|
100
|
+
**Blocker — planned ticket: <ticket-summary>**
|
|
101
|
+
|
|
102
|
+
The PRD as written can't produce a valid JIRA ticket for this scope. Specifically:
|
|
103
|
+
|
|
104
|
+
- **<gate-id> (<gate-name>)**: <reason>. *Fix:* <concrete remediation>.
|
|
105
|
+
- **<gate-id> (<gate-name>)**: <reason>. *Fix:* <concrete remediation>.
|
|
106
|
+
|
|
107
|
+
Once these are addressed in the PRD, set Status back to `Ready` and Claude will re-run intake.
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
3. Set `Status = Blocked` via `notion-update-page`.
|
|
111
|
+
4. Do NOT write any JIRA tickets.
|
|
112
|
+
|
|
113
|
+
Each comment must name the specific planned ticket and the specific gate — vague guidance is useless to product. The remediation field on the validator's report is already concrete; pass it through.
|
|
114
|
+
|
|
115
|
+
#### 3d. Continue
|
|
116
|
+
|
|
117
|
+
Move to the next Ready PRD. One PRD failing does not affect others.
|
|
118
|
+
|
|
119
|
+
### Phase 4 — Summary report
|
|
120
|
+
|
|
121
|
+
After processing every Ready PRD, emit a summary:
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
## notion-prd-intake summary
|
|
125
|
+
|
|
126
|
+
Database: <name> (<URL>)
|
|
127
|
+
Cycle started: <ISO timestamp>
|
|
128
|
+
Cycle completed: <ISO timestamp>
|
|
129
|
+
|
|
130
|
+
PRDs processed: <n>
|
|
131
|
+
- Ticketed: <n>
|
|
132
|
+
- <PRD title> → <epic-key> + <story-count> stories + <subtask-count> sub-tasks (coverage: COMPLETE | COMPLETE_WITH_SCOPE_CREEP)
|
|
133
|
+
- Blocked: <n>
|
|
134
|
+
- <PRD title> → <gate-failure-count> gate failures (pre-write) OR <gap-count> coverage gaps (post-write)
|
|
135
|
+
- Errors (claim failed, etc): <n>
|
|
136
|
+
- <PRD title> — <reason>
|
|
137
|
+
|
|
138
|
+
Total JIRA tickets created: <n>
|
|
139
|
+
Coverage audit summary: <n> COMPLETE / <n> COMPLETE_WITH_SCOPE_CREEP / <n> GAPS_FOUND
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Print to the agent's output. Do not write this summary to Notion or JIRA — it's an operational record for the human.
|
|
143
|
+
|
|
144
|
+
## Idempotency & safety
|
|
145
|
+
|
|
146
|
+
- **Single-cycle scope**: this skill processes the Ready set as it exists at the start of Phase 2. New `Ready` PRDs added mid-cycle are picked up next run.
|
|
147
|
+
- **No writes outside the lifecycle**: this skill only ever writes to JIRA via `notion-to-jira` (which delegates to `jira-write-ticket`), and only ever changes Notion `Status` to `In Review`, `Blocked`, or `Ticketed`. It never edits PRD content, never touches `Draft` or `Shipped`, never deletes pages.
|
|
148
|
+
- **Claim-first ordering**: `Status = In Review` is set BEFORE validation runs, so a re-entrant call won't double-process.
|
|
149
|
+
- **Failure isolation**: an exception processing one PRD must not stop the cycle. Catch, record under "Errors" in the summary, continue to the next PRD. The PRD that errored is left in `In Review` — the human investigates from there.
|
|
150
|
+
|
|
151
|
+
## Configuration
|
|
152
|
+
|
|
153
|
+
This skill reads project configuration from environment variables (or `$ARGUMENTS` overrides). If any required value is missing, ask the user before proceeding — never invent values.
|
|
154
|
+
|
|
155
|
+
| Variable | Purpose |
|
|
156
|
+
|----------|---------|
|
|
157
|
+
| `JIRA_PROJECT` | JIRA project key for ticket creation (passed to `notion-to-jira`) |
|
|
158
|
+
| `JIRA_SERVER` | Atlassian instance host |
|
|
159
|
+
| `E2E_BASE_URL` | Frontend URL for `product-walkthrough` |
|
|
160
|
+
| `E2E_TEST_PHONE` / `E2E_TEST_OTP` / `E2E_TEST_ORG` | Test user creds for walkthrough + verification plans |
|
|
161
|
+
| `E2E_GRAPHQL_URL` | API URL for verification plans |
|
|
162
|
+
|
|
163
|
+
## Rules
|
|
164
|
+
|
|
165
|
+
- Never write to JIRA outside of `notion-to-jira` → `jira-write-ticket`. The validator's verdict gates progress; bypassing it produces broken tickets.
|
|
166
|
+
- Never set Notion `Status` to a value this skill doesn't own (`In Review`, `Blocked`, `Ticketed`). Product owns `Draft`, `Ready`, `Shipped`.
|
|
167
|
+
- Never edit the PRD's body. Communication with product happens only through Notion comments.
|
|
168
|
+
- Never run more than one intake cycle concurrently against the same database. This skill assumes serial execution. (Scheduling is a separate concern; the runtime should not start a new cycle if a previous one is still in flight.)
|
|
169
|
+
- If `notion-to-jira` returns errors (e.g. unreachable artifact, malformed PRD structure), treat them as gate failures: comment + Blocked. Don't silently fail.
|