@codyswann/lisa 1.94.0 → 1.96.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.
Files changed (104) hide show
  1. package/dist/cli/index.d.ts.map +1 -1
  2. package/dist/cli/index.js +41 -5
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/codex/agent-installer.d.ts +56 -0
  5. package/dist/codex/agent-installer.d.ts.map +1 -0
  6. package/dist/codex/agent-installer.js +201 -0
  7. package/dist/codex/agent-installer.js.map +1 -0
  8. package/dist/codex/agent-transformer.d.ts +53 -0
  9. package/dist/codex/agent-transformer.d.ts.map +1 -0
  10. package/dist/codex/agent-transformer.js +181 -0
  11. package/dist/codex/agent-transformer.js.map +1 -0
  12. package/dist/codex/agents-md-installer.d.ts +24 -0
  13. package/dist/codex/agents-md-installer.d.ts.map +1 -0
  14. package/dist/codex/agents-md-installer.js +63 -0
  15. package/dist/codex/agents-md-installer.js.map +1 -0
  16. package/dist/codex/hooks-installer.d.ts +24 -0
  17. package/dist/codex/hooks-installer.d.ts.map +1 -0
  18. package/dist/codex/hooks-installer.js +206 -0
  19. package/dist/codex/hooks-installer.js.map +1 -0
  20. package/dist/codex/hooks-merger.d.ts +82 -0
  21. package/dist/codex/hooks-merger.d.ts.map +1 -0
  22. package/dist/codex/hooks-merger.js +127 -0
  23. package/dist/codex/hooks-merger.js.map +1 -0
  24. package/dist/codex/manifest.d.ts +32 -0
  25. package/dist/codex/manifest.d.ts.map +1 -0
  26. package/dist/codex/manifest.js +86 -0
  27. package/dist/codex/manifest.js.map +1 -0
  28. package/dist/codex/settings-installer.d.ts +48 -0
  29. package/dist/codex/settings-installer.d.ts.map +1 -0
  30. package/dist/codex/settings-installer.js +276 -0
  31. package/dist/codex/settings-installer.js.map +1 -0
  32. package/dist/codex/skills-installer.d.ts +46 -0
  33. package/dist/codex/skills-installer.d.ts.map +1 -0
  34. package/dist/codex/skills-installer.js +344 -0
  35. package/dist/codex/skills-installer.js.map +1 -0
  36. package/dist/core/config.d.ts +19 -0
  37. package/dist/core/config.d.ts.map +1 -1
  38. package/dist/core/config.js +13 -0
  39. package/dist/core/config.js.map +1 -1
  40. package/dist/core/lisa.d.ts +12 -0
  41. package/dist/core/lisa.d.ts.map +1 -1
  42. package/dist/core/lisa.js +48 -0
  43. package/dist/core/lisa.js.map +1 -1
  44. package/dist/core/project-config.d.ts +49 -0
  45. package/dist/core/project-config.d.ts.map +1 -0
  46. package/dist/core/project-config.js +119 -0
  47. package/dist/core/project-config.js.map +1 -0
  48. package/package.json +3 -1
  49. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa/agents/jira-agent.md +21 -8
  51. package/plugins/lisa/agents/jira-build-intake.md +58 -0
  52. package/plugins/lisa/agents/notion-prd-intake.md +57 -0
  53. package/plugins/lisa/commands/jira/build-intake.md +7 -0
  54. package/plugins/lisa/commands/jira/source-artifacts.md +6 -0
  55. package/plugins/lisa/commands/jira/validate-ticket.md +7 -0
  56. package/plugins/lisa/commands/notion-prd-intake.md +7 -0
  57. package/plugins/lisa/commands/prd-ticket-coverage.md +7 -0
  58. package/plugins/lisa/commands/product-walkthrough.md +7 -0
  59. package/plugins/lisa/rules/base-rules.md +9 -1
  60. package/plugins/lisa/skills/jira-build-intake/SKILL.md +134 -0
  61. package/plugins/lisa/skills/jira-create/SKILL.md +53 -30
  62. package/plugins/lisa/skills/jira-source-artifacts/SKILL.md +107 -0
  63. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +224 -0
  64. package/plugins/lisa/skills/jira-verify/SKILL.md +15 -35
  65. package/plugins/lisa/skills/jira-write-ticket/SKILL.md +72 -19
  66. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +169 -0
  67. package/plugins/lisa/skills/notion-to-jira/SKILL.md +137 -95
  68. package/plugins/lisa/skills/prd-ticket-coverage/SKILL.md +137 -0
  69. package/plugins/lisa/skills/product-walkthrough/SKILL.md +129 -0
  70. package/plugins/lisa/skills/ticket-triage/SKILL.md +19 -2
  71. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-expo/skills/jira-create/SKILL.md +60 -28
  74. package/plugins/lisa-expo/skills/jira-verify/SKILL.md +14 -34
  75. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-rails/skills/jira-create/SKILL.md +59 -28
  78. package/plugins/lisa-rails/skills/jira-verify/SKILL.md +13 -16
  79. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  80. package/plugins/src/base/agents/jira-agent.md +21 -8
  81. package/plugins/src/base/agents/jira-build-intake.md +58 -0
  82. package/plugins/src/base/agents/notion-prd-intake.md +57 -0
  83. package/plugins/src/base/commands/jira/build-intake.md +7 -0
  84. package/plugins/src/base/commands/jira/source-artifacts.md +6 -0
  85. package/plugins/src/base/commands/jira/validate-ticket.md +7 -0
  86. package/plugins/src/base/commands/notion-prd-intake.md +7 -0
  87. package/plugins/src/base/commands/prd-ticket-coverage.md +7 -0
  88. package/plugins/src/base/commands/product-walkthrough.md +7 -0
  89. package/plugins/src/base/rules/base-rules.md +9 -1
  90. package/plugins/src/base/skills/jira-build-intake/SKILL.md +134 -0
  91. package/plugins/src/base/skills/jira-create/SKILL.md +53 -30
  92. package/plugins/src/base/skills/jira-source-artifacts/SKILL.md +107 -0
  93. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +224 -0
  94. package/plugins/src/base/skills/jira-verify/SKILL.md +15 -35
  95. package/plugins/src/base/skills/jira-write-ticket/SKILL.md +72 -19
  96. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +169 -0
  97. package/plugins/src/base/skills/notion-to-jira/SKILL.md +137 -95
  98. package/plugins/src/base/skills/prd-ticket-coverage/SKILL.md +137 -0
  99. package/plugins/src/base/skills/product-walkthrough/SKILL.md +129 -0
  100. package/plugins/src/base/skills/ticket-triage/SKILL.md +19 -2
  101. package/plugins/src/expo/skills/jira-create/SKILL.md +60 -28
  102. package/plugins/src/expo/skills/jira-verify/SKILL.md +14 -34
  103. package/plugins/src/rails/skills/jira-create/SKILL.md +59 -28
  104. package/plugins/src/rails/skills/jira-verify/SKILL.md +13 -16
@@ -1,48 +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 checks epic parent relationships and validates description completeness for coding assistants, developers, and stakeholders.
4
- allowed-tools: ["mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
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
- Fetch ticket $ARGUMENTS and verify it meets organizational standards.
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
- ## Verification Checks
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
- ### 1. Epic Parent Relationship
13
+ ## Process
14
14
 
15
- **Rule**: Non-bug, non-epic tickets MUST have an epic parent
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
- - If missing: Search filter 10089 (Epic Backlog) and suggest appropriate epics
20
+ ## Output
18
21
 
19
- ### 2. Description Quality
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
- Verify description adequately addresses:
24
+ ## Notes
22
25
 
23
- **Coding Assistants**: Acceptance criteria, requirements, constraints, I/O
24
- **Developers**: Technical context, integration points, testing, edge cases
25
- **Stakeholders**: Business value, user impact, success metrics, summary
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
- ## Execute Verification
47
-
48
- Retrieve ticket details, run all checks, and provide specific improvement recommendations for any failures.
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.
@@ -26,13 +26,16 @@ Required fields (stop and ask if missing — do not invent values):
26
26
  | Field | Required For | Notes |
27
27
  |-------|--------------|-------|
28
28
  | Project key | CREATE | Call `getVisibleJiraProjects` if unknown |
29
- | Issue type | CREATE | Story, Task, Bug, Epic, Spike, Improvement |
29
+ | Issue type | CREATE | Story, Task, Bug, Epic, Spike, Sub-task, Improvement |
30
30
  | Summary | CREATE, UPDATE | One line, imperative voice, under 100 chars |
31
31
  | Description | CREATE, UPDATE | Multi-section — see Phase 3 |
32
32
  | Epic parent | Non-bug, non-epic | Enforced by `jira-verify` |
33
33
  | Priority | CREATE | Default to project default if unstated |
34
- | Acceptance criteria | Story, Task, Bug, Improvement | Gherkin — see Phase 3 |
34
+ | Acceptance criteria | Story, Task, Bug, Sub-task, Improvement | Gherkin — see Phase 3 |
35
35
  | Validation Journey | Runtime-behavior changes | Delegate to `/jira-add-journey` |
36
+ | Target backend environment | Runtime-behavior changes | `dev` / `staging` / `prod`; recorded in description (Phase 3). Skip only for doc/config/type-only tickets. |
37
+ | Sign-in account / credentials | Tickets that touch authenticated surfaces | Name the account (or source — 1Password item, env var, seeded fixture) and role; recorded in description (Phase 3). Omit when sign-in is not required. |
38
+ | Single-repo scope | Bug, Task, Sub-task | These types MUST cover one repo only. If the work crosses repos, split it before creating. Epic / Spike / Story may span repos. |
36
39
 
37
40
  Optional but recommended: assignee, components, fix versions, labels, sprint, story points, reporter.
38
41
 
@@ -62,6 +65,26 @@ h2. Acceptance Criteria
62
65
  h2. Out of Scope
63
66
  [Explicit list of what this ticket does NOT cover. Forces scope discipline.]
64
67
 
68
+ h2. Target Backend Environment
69
+ [Required when the ticket changes runtime behavior. One of: dev / staging / prod.
70
+ This is the environment QA/product reported against and the backend the
71
+ implementer points their local stack at during verification before CI/CD.
72
+ Backend-only tickets state the deployed env they target. Skip section
73
+ entirely for doc-only, config-only, or type-only tickets.]
74
+
75
+ h2. Sign-in Required
76
+ [Include this section ONLY if the work touches authenticated surfaces.
77
+ Specify: the account/role to sign in as, where to get the credentials
78
+ (1Password item name, env var, seeded fixture), and any MFA/SSO notes.
79
+ Omit the section entirely when sign-in is not required — its absence
80
+ means "no sign-in needed for this ticket."]
81
+
82
+ h2. Repository
83
+ [Required for Bug / Task / Sub-task. Name the single repo this ticket covers.
84
+ If the work spans repos, this ticket type is wrong — split into per-repo
85
+ Tasks/Subtasks under a parent Story or Epic. Epic / Spike / Story may
86
+ list multiple repos.]
87
+
65
88
  h2. Validation Journey
66
89
  [Delegate to /jira-add-journey if the ticket changes runtime behavior.
67
90
  Skip only for doc-only, config-only, or type-only tickets.]
@@ -72,6 +95,7 @@ Rules:
72
95
  - Every criterion is independently verifiable (UI, API, data, or performance check).
73
96
  - If the ticket is a Bug, include reproduction steps, expected vs. actual behavior, and environment.
74
97
  - If the ticket is a Spike, include the question being answered and the definition of done (decision doc, prototype, or findings).
98
+ - If sign-in is required, the implementer must be able to sign in from the description alone — never assume they will guess the account or hunt for credentials.
75
99
 
76
100
  ## Phase 4 — Relationship Discovery (Mandatory)
77
101
 
@@ -91,7 +115,24 @@ If the ticket is not a Bug and not an Epic, it MUST have an epic parent:
91
115
 
92
116
  ### 4b. Related Tickets
93
117
 
94
- Run targeted JQL searches to surface candidate links. Present candidates to the human (or record them on the ticket as a comment) before skipping. Suggested searches:
118
+ Relationship discovery is **mandatory** on every create and every update never declare "no related work" without doing both searches below and recording their outcomes on the ticket.
119
+
120
+ **Search 1: local git history** (catches PRs/commits that touched the same area but were never linked to a ticket):
121
+
122
+ ```bash
123
+ # Commits mentioning the keyword
124
+ git log --all --oneline --grep="<keyword>"
125
+
126
+ # Commits that touched the relevant paths
127
+ git log --all --oneline -- <path-or-glob>
128
+
129
+ # Recent activity in this area (last 90 days)
130
+ git log --since=90.days --oneline -- <path-or-glob>
131
+ ```
132
+
133
+ If the git search surfaces a PR or commit that relates to this work, capture the PR URL — it becomes a remote link (Phase 4c) and may also point to a sibling ticket worth linking.
134
+
135
+ **Search 2: Jira JQL** (catches open and recently-closed tickets):
95
136
 
96
137
  ```jql
97
138
  # Open tickets touching the same component
@@ -105,8 +146,13 @@ project = <PROJECT> AND (summary ~ "<keyword>" OR description ~ "<keyword>") AND
105
146
 
106
147
  # Recent tickets touching the same labels
107
148
  project = <PROJECT> AND labels in (<labels>) AND updated >= -30d
149
+
150
+ # Recently closed tickets in the same area (catches duplicates of work just shipped)
151
+ project = <PROJECT> AND component = "<component>" AND status = Done AND updated >= -30d
108
152
  ```
109
153
 
154
+ **Record the outcome.** Add a `## Relationship Search` subsection (or a comment if updating an existing ticket) listing the queries you ran and what they returned. If the searches yielded nothing, write that explicitly — "Searched git history for `<keywords>` and JQL for component=`X`, label=`Y`, epic siblings; no related work found." A ticket with zero links and no documented search is rejected.
155
+
110
156
  For each candidate, classify the relationship:
111
157
 
112
158
  | Link Type | When to Use |
@@ -124,28 +170,19 @@ Identify and attach:
124
170
  - Confluence pages (design docs, RFCs, runbooks)
125
171
  - Dashboards (Grafana, Datadog, Sentry issue)
126
172
  - Incident tickets (PagerDuty, Statuspage)
127
- - **Source artifacts from the originating PRD / parent epic**: Figma files, Lovable prototypes, Loom walkthroughs, design mockups, example payloads, Google Docs/Slides, collaborative whiteboards. If this ticket has a parent epic, enumerate the 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 generic `reference` links). Never assume a developer will walk up to the epic to find design context — attach it here.
128
-
129
- Domain disambiguation (applied on inheritance):
130
- - Figma URL with `/proto/` in path or `starting-point-node-id=` in query → `ux-flow`; otherwise `ui-design`.
131
- - Lovable output → always `ux-flow`; its code/styling is not authoritative.
132
- - Loom / annotated screenshot → `ux-flow`.
133
- - 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.
134
174
 
135
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.
136
176
 
137
177
  ### 4d. Source Precedence (must appear on the ticket)
138
178
 
139
- When a ticket carries both design artifacts and a description, different sources are authoritative for different questions. Record this precedence explicitly in the ticket description (under Technical Approach or a dedicated `## Source Precedence` subsection) so the implementer doesn't silently reconcile conflicts:
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.
140
180
 
141
- - **Business rules** (required fields, validation, permissions, data constraints, edge cases) the **description / PRD body** wins.
142
- - **Visual treatment** (layout, spacing, typography, color, iconography) → **mocks (`ui-design`)** win.
143
- - **Flow and interaction** (navigation, transitions, state changes, timing, empty/error/loading states) → **prototypes (`ux-flow`)** win.
144
- - **API / data shape** → **`data` artifacts** win.
181
+ For UI-touching tickets, include the existing-component reuse expectation per `jira-source-artifacts` §7.
145
182
 
146
- Cross-axis conflicts (mock shows a field the PRD doesn't mention; prototype shows a flow the PRD contradicts; two Figma links disagree) must be raised as BLOCKER items in an `## Open Questions` section on the ticket — never silently reconciled.
183
+ ### 4e. Live Product Walkthrough Findings (UI-touching tickets)
147
184
 
148
- For UI-touching tickets, additionally include the reuse expectation: "Before implementing, identify the closest existing component in the codebase. Prefer reuse even if the mock specifies different styling; raise design-vs-code divergence as a discussion item here rather than pixel-matching from scratch."
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.
149
186
 
150
187
  Use Jira's web UI or `mcp__atlassian__editJiraIssue` to set the `Development` field / remote links where supported.
151
188
 
@@ -161,6 +198,19 @@ Before create/update, verify each field is populated where applicable:
161
198
  - Sprint: only if actively sprinting this work
162
199
  - Assignee: leave unset if unknown rather than auto-assigning
163
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
+
164
214
  ## Phase 6 — Create or Update
165
215
 
166
216
  ### CREATE
@@ -179,7 +229,7 @@ Before create/update, verify each field is populated where applicable:
179
229
 
180
230
  ## Phase 7 — Verify
181
231
 
182
- 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.
183
233
 
184
234
  ## Phase 8 — Announce
185
235
 
@@ -194,7 +244,10 @@ Skip this step only on UPDATE when no material change was made.
194
244
  ## Rules
195
245
 
196
246
  - Never create a non-bug ticket without an epic parent.
197
- - Never skip relationship discovery — record "none found" explicitly if the search returned nothing.
247
+ - Never skip relationship discovery — both the git history search AND the JQL search must run, and their outcomes must be recorded on the ticket. "None found" is acceptable only when it's documented.
248
+ - Never create a Bug, Task, or Sub-task that spans multiple repos. Split it before creating.
249
+ - Never include a runtime-behavior ticket without a target backend environment, and never include an authenticated-surface ticket without sign-in credentials in the description.
198
250
  - Never invent custom field values. If the project requires a field you don't have, stop and ask.
199
251
  - Never overwrite a description without reading the current version first.
200
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.