@codyswann/lisa 2.21.1 → 2.23.1

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 (152) hide show
  1. package/package.json +3 -2
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/agents/confluence-prd-intake.md +11 -9
  5. package/plugins/lisa/agents/github-agent.md +18 -10
  6. package/plugins/lisa/agents/github-build-intake.md +10 -8
  7. package/plugins/lisa/agents/github-prd-intake.md +11 -9
  8. package/plugins/lisa/agents/jira-agent.md +12 -8
  9. package/plugins/lisa/agents/jira-build-intake.md +9 -7
  10. package/plugins/lisa/agents/learnings-synthesizer.md +1 -1
  11. package/plugins/lisa/agents/linear-agent.md +15 -9
  12. package/plugins/lisa/agents/linear-build-intake.md +13 -11
  13. package/plugins/lisa/agents/linear-prd-intake.md +11 -9
  14. package/plugins/lisa/agents/notion-prd-intake.md +11 -9
  15. package/plugins/lisa/agents/pr-mining-specialist.md +1 -1
  16. package/plugins/lisa/agents/tracker-mining-specialist.md +1 -1
  17. package/plugins/lisa/commands/setup/atlassian.md +7 -0
  18. package/plugins/lisa/commands/setup/confluence.md +7 -0
  19. package/plugins/lisa/commands/setup/jira.md +7 -0
  20. package/plugins/lisa/commands/setup/notion.md +7 -0
  21. package/plugins/lisa/hooks/enforce-team-first.sh +14 -6
  22. package/plugins/lisa/rules/base-rules.md +3 -3
  23. package/plugins/lisa/rules/config-resolution.md +242 -24
  24. package/plugins/lisa/rules/intent-routing.md +4 -4
  25. package/plugins/lisa/rules/repo-scope-split.md +41 -0
  26. package/plugins/lisa/rules/verification.md +13 -0
  27. package/plugins/lisa/skills/atlassian-access/SKILL.md +260 -0
  28. package/plugins/lisa/skills/confluence-prd-intake/SKILL.md +167 -82
  29. package/plugins/lisa/skills/confluence-to-tracker/SKILL.md +39 -26
  30. package/plugins/lisa/skills/debrief/SKILL.md +4 -5
  31. package/plugins/lisa/skills/github-add-journey/SKILL.md +1 -0
  32. package/plugins/lisa/skills/github-build-intake/SKILL.md +104 -40
  33. package/plugins/lisa/skills/github-evidence/SKILL.md +22 -5
  34. package/plugins/lisa/skills/github-prd-intake/SKILL.md +87 -51
  35. package/plugins/lisa/skills/github-to-tracker/SKILL.md +2 -2
  36. package/plugins/lisa/skills/github-validate-issue/SKILL.md +11 -1
  37. package/plugins/lisa/skills/implement/SKILL.md +5 -6
  38. package/plugins/lisa/skills/intake/SKILL.md +5 -6
  39. package/plugins/lisa/skills/jira-add-journey/SKILL.md +1 -0
  40. package/plugins/lisa/skills/jira-build-intake/SKILL.md +110 -45
  41. package/plugins/lisa/skills/jira-create/SKILL.md +5 -3
  42. package/plugins/lisa/skills/jira-evidence/SKILL.md +19 -2
  43. package/plugins/lisa/skills/jira-journey/SKILL.md +3 -1
  44. package/plugins/lisa/skills/jira-read-ticket/SKILL.md +10 -8
  45. package/plugins/lisa/skills/jira-sync/SKILL.md +11 -5
  46. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +22 -10
  47. package/plugins/lisa/skills/jira-verify/SKILL.md +5 -3
  48. package/plugins/lisa/skills/jira-write-ticket/SKILL.md +16 -14
  49. package/plugins/lisa/skills/linear-add-journey/SKILL.md +1 -0
  50. package/plugins/lisa/skills/linear-build-intake/SKILL.md +90 -32
  51. package/plugins/lisa/skills/linear-evidence/SKILL.md +22 -5
  52. package/plugins/lisa/skills/linear-prd-intake/SKILL.md +92 -57
  53. package/plugins/lisa/skills/linear-validate-issue/SKILL.md +10 -0
  54. package/plugins/lisa/skills/monitor/SKILL.md +4 -5
  55. package/plugins/lisa/skills/notion-access/SKILL.md +193 -0
  56. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +105 -46
  57. package/plugins/lisa/skills/notion-to-tracker/SKILL.md +7 -5
  58. package/plugins/lisa/skills/plan/SKILL.md +4 -5
  59. package/plugins/lisa/skills/research/SKILL.md +4 -5
  60. package/plugins/lisa/skills/setup-atlassian/SKILL.md +316 -0
  61. package/plugins/lisa/skills/setup-confluence/SKILL.md +245 -0
  62. package/plugins/lisa/skills/setup-jira/SKILL.md +198 -0
  63. package/plugins/lisa/skills/setup-notion/SKILL.md +283 -0
  64. package/plugins/lisa/skills/task-decomposition/SKILL.md +2 -0
  65. package/plugins/lisa/skills/ticket-triage/SKILL.md +4 -1
  66. package/plugins/lisa/skills/tracker-evidence/SKILL.md +1 -0
  67. package/plugins/lisa/skills/verification-lifecycle/SKILL.md +2 -0
  68. package/plugins/lisa/skills/verify/SKILL.md +4 -5
  69. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  73. package/plugins/lisa-expo/skills/ops-browser-uat/SKILL.md +1 -1
  74. package/plugins/lisa-expo/skills/ops-check-logs/SKILL.md +1 -1
  75. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  77. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  79. package/plugins/lisa-nestjs/skills/nestjs-graphql/references/project-patterns.md +48 -0
  80. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  82. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  84. package/plugins/src/base/agents/confluence-prd-intake.md +11 -9
  85. package/plugins/src/base/agents/github-agent.md +18 -10
  86. package/plugins/src/base/agents/github-build-intake.md +10 -8
  87. package/plugins/src/base/agents/github-prd-intake.md +11 -9
  88. package/plugins/src/base/agents/jira-agent.md +12 -8
  89. package/plugins/src/base/agents/jira-build-intake.md +9 -7
  90. package/plugins/src/base/agents/learnings-synthesizer.md +1 -1
  91. package/plugins/src/base/agents/linear-agent.md +15 -9
  92. package/plugins/src/base/agents/linear-build-intake.md +13 -11
  93. package/plugins/src/base/agents/linear-prd-intake.md +11 -9
  94. package/plugins/src/base/agents/notion-prd-intake.md +11 -9
  95. package/plugins/src/base/agents/pr-mining-specialist.md +1 -1
  96. package/plugins/src/base/agents/tracker-mining-specialist.md +1 -1
  97. package/plugins/src/base/commands/setup/atlassian.md +7 -0
  98. package/plugins/src/base/commands/setup/confluence.md +7 -0
  99. package/plugins/src/base/commands/setup/jira.md +7 -0
  100. package/plugins/src/base/commands/setup/notion.md +7 -0
  101. package/plugins/src/base/hooks/enforce-team-first.sh +14 -6
  102. package/plugins/src/base/rules/base-rules.md +3 -3
  103. package/plugins/src/base/rules/config-resolution.md +242 -24
  104. package/plugins/src/base/rules/intent-routing.md +4 -4
  105. package/plugins/src/base/rules/repo-scope-split.md +41 -0
  106. package/plugins/src/base/rules/verification.md +13 -0
  107. package/plugins/src/base/skills/atlassian-access/SKILL.md +260 -0
  108. package/plugins/src/base/skills/confluence-prd-intake/SKILL.md +167 -82
  109. package/plugins/src/base/skills/confluence-to-tracker/SKILL.md +39 -26
  110. package/plugins/src/base/skills/debrief/SKILL.md +4 -5
  111. package/plugins/src/base/skills/github-add-journey/SKILL.md +1 -0
  112. package/plugins/src/base/skills/github-build-intake/SKILL.md +104 -40
  113. package/plugins/src/base/skills/github-evidence/SKILL.md +22 -5
  114. package/plugins/src/base/skills/github-prd-intake/SKILL.md +87 -51
  115. package/plugins/src/base/skills/github-to-tracker/SKILL.md +2 -2
  116. package/plugins/src/base/skills/github-validate-issue/SKILL.md +11 -1
  117. package/plugins/src/base/skills/implement/SKILL.md +5 -6
  118. package/plugins/src/base/skills/intake/SKILL.md +5 -6
  119. package/plugins/src/base/skills/jira-add-journey/SKILL.md +1 -0
  120. package/plugins/src/base/skills/jira-build-intake/SKILL.md +110 -45
  121. package/plugins/src/base/skills/jira-create/SKILL.md +5 -3
  122. package/plugins/src/base/skills/jira-evidence/SKILL.md +19 -2
  123. package/plugins/src/base/skills/jira-journey/SKILL.md +3 -1
  124. package/plugins/src/base/skills/jira-read-ticket/SKILL.md +10 -8
  125. package/plugins/src/base/skills/jira-sync/SKILL.md +11 -5
  126. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +22 -10
  127. package/plugins/src/base/skills/jira-verify/SKILL.md +5 -3
  128. package/plugins/src/base/skills/jira-write-ticket/SKILL.md +16 -14
  129. package/plugins/src/base/skills/linear-add-journey/SKILL.md +1 -0
  130. package/plugins/src/base/skills/linear-build-intake/SKILL.md +90 -32
  131. package/plugins/src/base/skills/linear-evidence/SKILL.md +22 -5
  132. package/plugins/src/base/skills/linear-prd-intake/SKILL.md +92 -57
  133. package/plugins/src/base/skills/linear-validate-issue/SKILL.md +10 -0
  134. package/plugins/src/base/skills/monitor/SKILL.md +4 -5
  135. package/plugins/src/base/skills/notion-access/SKILL.md +193 -0
  136. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +105 -46
  137. package/plugins/src/base/skills/notion-to-tracker/SKILL.md +7 -5
  138. package/plugins/src/base/skills/plan/SKILL.md +4 -5
  139. package/plugins/src/base/skills/research/SKILL.md +4 -5
  140. package/plugins/src/base/skills/setup-atlassian/SKILL.md +316 -0
  141. package/plugins/src/base/skills/setup-confluence/SKILL.md +245 -0
  142. package/plugins/src/base/skills/setup-jira/SKILL.md +198 -0
  143. package/plugins/src/base/skills/setup-notion/SKILL.md +283 -0
  144. package/plugins/src/base/skills/task-decomposition/SKILL.md +2 -0
  145. package/plugins/src/base/skills/ticket-triage/SKILL.md +4 -1
  146. package/plugins/src/base/skills/tracker-evidence/SKILL.md +1 -0
  147. package/plugins/src/base/skills/verification-lifecycle/SKILL.md +2 -0
  148. package/plugins/src/base/skills/verify/SKILL.md +4 -5
  149. package/plugins/src/expo/skills/ops-browser-uat/SKILL.md +1 -1
  150. package/plugins/src/expo/skills/ops-check-logs/SKILL.md +1 -1
  151. package/plugins/src/nestjs/skills/nestjs-graphql/references/project-patterns.md +48 -0
  152. package/scripts/check-plugins-sync.sh +45 -0
@@ -1,21 +1,78 @@
1
1
  ---
2
2
  name: jira-build-intake
3
- description: "Symmetric counterpart to notion-prd-intake on the JIRA side. Scans a JIRA project (or JQL filter) for tickets in Status=Ready, claims each by transitioning to In Progress, runs the implementation/build flow via jira-agent, and transitions to On Dev on completion. The Ready status is the human-flipped signal that a TODO ticket is truly ready for development — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
4
- allowed-tools: ["Skill", "Bash", "mcp__atlassian__getAccessibleAtlassianResources", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getJiraIssue", "mcp__atlassian__getTransitionsForJiraIssue", "mcp__atlassian__transitionJiraIssue", "mcp__atlassian__addCommentToJiraIssue"]
3
+ description: "Symmetric counterpart to notion-prd-intake on the JIRA side. Scans a JIRA project (or JQL filter) for tickets in the configured `ready` status, claims each by transitioning to the configured `claimed` status, runs the implementation/build flow via jira-agent, and transitions to the configured `done` status on completion. The `ready` status is the human-flipped signal that a TODO ticket is truly ready for development — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
4
+ allowed-tools: ["Skill", "Bash"]
5
5
  ---
6
6
 
7
7
  # JIRA Build Intake: $ARGUMENTS
8
8
 
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
10
+
9
11
  `$ARGUMENTS` is one of:
10
12
 
11
- 1. A JIRA project key (e.g. `SE`) — scans that project for `Status = Ready` tickets.
12
- 2. A full JQL filter (e.g. `project = SE AND component = "frontend" AND Status = Ready`) — used as-is. The skill will not append a `Status = Ready` clause if the JQL already names a status, so callers can intentionally widen.
13
+ 1. A JIRA project key (e.g. `SE`) — scans that project for tickets in the configured `ready` status.
14
+ 2. A full JQL filter (e.g. `project = SE AND component = "frontend" AND Status = Ready`) — used as-is. The skill will not append a `Status = <ready>` clause if the JQL already names a status, so callers can intentionally widen.
15
+
16
+ Run one build-intake cycle. Each ready ticket is claimed, built via the `lisa:jira-agent` flow, and transitioned to the configured `done` status (env-aware — see below). The cycle is the symmetric mirror of `lisa:notion-prd-intake`: humans flip the ready status, agents pick up and progress.
17
+
18
+ ## Workflow resolution
13
19
 
14
- Run one build-intake cycle. Each Ready ticket is claimed, built via the `lisa:jira-agent` flow, and transitioned to `On Dev` (or the equivalent next-status for that project). The cycle is the symmetric mirror of `lisa:notion-prd-intake`: humans flip `Ready`, agents pick up and progress.
20
+ Status names are read from `.lisa.config.json` `jira.workflow.*`, falling back to defaults documented in the `config-resolution` rule. Bash pattern:
21
+
22
+ ```bash
23
+ # Read role with default fallback. Local overrides global per-key.
24
+ read_role() {
25
+ local role="$1" default="$2"
26
+ local local_v global_v
27
+ local_v=$(jq -r ".jira.workflow.${role} // empty" .lisa.config.local.json 2>/dev/null)
28
+ global_v=$(jq -r ".jira.workflow.${role} // empty" .lisa.config.json 2>/dev/null)
29
+ echo "${local_v:-${global_v:-$default}}"
30
+ }
31
+
32
+ READY=$(read_role ready "Ready")
33
+ CLAIMED=$(read_role claimed "In Progress")
34
+ ```
35
+
36
+ For env-keyed `done`, resolve the env first, then look up `done[<env>]`:
37
+
38
+ 1. Explicit caller arg (`target_env=staging`) wins.
39
+ 2. Otherwise, infer the env from the PR's base branch via `deploy.branches` (reverse lookup: if base is `staging`, env is `staging`).
40
+ 3. If `done` in config is a **string** (not a map), use it directly regardless of env.
41
+ 4. If `done` is a **map** and env cannot be resolved, **fail loudly** — do not pick arbitrarily.
42
+
43
+ ```bash
44
+ # Resolve env, then DONE.
45
+ TARGET_ENV="${target_env:-}" # from caller args if supplied
46
+ if [ -z "$TARGET_ENV" ] && [ -n "$PR_BASE_BRANCH" ]; then
47
+ TARGET_ENV=$(jq -r --arg b "$PR_BASE_BRANCH" \
48
+ '.deploy.branches // {} | to_entries[] | select(.value == $b) | .key' \
49
+ .lisa.config.json 2>/dev/null | head -1)
50
+ fi
51
+
52
+ DONE_RAW=$(jq -r '.jira.workflow.done // empty' .lisa.config.json 2>/dev/null)
53
+ DONE_TYPE=$(jq -r '.jira.workflow.done | type' .lisa.config.json 2>/dev/null)
54
+ if [ "$DONE_TYPE" = "string" ]; then
55
+ DONE="$DONE_RAW"
56
+ elif [ "$DONE_TYPE" = "object" ]; then
57
+ [ -z "$TARGET_ENV" ] && { echo "ERROR: jira.workflow.done is env-keyed but env not resolvable"; exit 1; }
58
+ DONE=$(jq -r --arg e "$TARGET_ENV" '.jira.workflow.done[$e] // empty' .lisa.config.json)
59
+ [ -z "$DONE" ] && { echo "ERROR: jira.workflow.done has no entry for env '$TARGET_ENV'"; exit 1; }
60
+ else
61
+ # Default: env-keyed map matching legacy hardcoded names.
62
+ case "$TARGET_ENV" in
63
+ dev) DONE="On Dev" ;;
64
+ staging) DONE="On Stg" ;;
65
+ production) DONE="Done" ;;
66
+ *) echo "ERROR: cannot resolve done status without env"; exit 1 ;;
67
+ esac
68
+ fi
69
+ ```
70
+
71
+ Run one build-intake cycle. Each ticket in `$READY` is claimed by transitioning to `$CLAIMED`, built via the `lisa:jira-agent` flow, and transitioned to `$DONE` on completion.
15
72
 
16
73
  ## Confirmation policy
17
74
 
18
- Do NOT ask the caller whether to proceed. Once invoked with a project key or JQL, run the cycle to completion — claim, dispatch each ticket through `lisa:jira-agent`, transition successful builds to `On Dev`, write the summary. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background batch.
75
+ Do NOT ask the caller whether to proceed. Once invoked with a project key or JQL, run the cycle to completion — claim, dispatch each ticket through `lisa:jira-agent`, transition successful builds to `$DONE`, write the summary. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background batch.
19
76
 
20
77
  Specifically forbidden:
21
78
 
@@ -27,46 +84,45 @@ Specifically forbidden:
27
84
  The only legitimate reasons to stop early:
28
85
 
29
86
  - Missing project key / JQL or required configuration. Surface the missing value and exit.
30
- - Workflow misconfigured (pre-flight check finds `In Progress` or `On Dev` not reachable, or `Ready` status absent). Surface and exit.
31
- - Empty `Ready` set. Exit cleanly with `"No tickets with Status=Ready. Nothing to do."`
87
+ - Workflow misconfigured (pre-flight check finds `$CLAIMED` or `$DONE` not reachable, or `$READY` status absent). Surface and exit.
88
+ - Empty ready set. Exit cleanly with `"No tickets with Status=$READY. Nothing to do."`
32
89
 
33
90
  ## Lifecycle assumed
34
91
 
35
- The JIRA workflow has these statuses (or equivalents — see Configuration for renaming):
92
+ The JIRA workflow has these statuses (configured per project — see Workflow resolution above for how role names map to actual workflow values):
36
93
 
37
94
  ```text
38
- TODO → ReadyIn Progress On Dev → On QA → Done
39
- (PM/ (us claim) (us done; (downstream)
40
- human) PR ready)
95
+ TODO → readyclaimeddone(env-keyed) → On QA → archive
96
+ (PM/ (us claim) (us done; (downstream)
97
+ human) PR ready)
41
98
  ```
42
99
 
43
- This skill ONLY transitions `ReadyIn Progress` on claim, and `In Progress On Dev` on completion. It never touches `TODO`, `On QA`, `Done`, or any blocked/closed states.
100
+ This skill ONLY transitions `$READY$CLAIMED` on claim, and `$CLAIMED$DONE` on completion. It never touches `TODO`, post-`done` statuses, or any blocked/closed states.
44
101
 
45
- **Pre-flight check**: at start of each cycle, call `getTransitionsForJiraIssue` against a sample Ready ticket to confirm `In Progress` and `On Dev` are reachable transitions. If not, stop and report the workflow misconfiguration to the caller — do not invent transitions.
102
+ **Pre-flight check**: at start of each cycle, attempt the `$CLAIMED` and `$DONE` transitions against a sample ready ticket via `lisa:atlassian-access` `operation: transition key: <K> to: "<status>"` (in a probe / dry-run sense — or fetch transition metadata if the access skill exposes that). If the transitions are unreachable, stop and report the workflow misconfiguration to the caller — do not invent transitions.
46
103
 
47
104
  ## Phases
48
105
 
49
106
  ### Phase 1 — Resolve the query
50
107
 
51
108
  1. Parse `$ARGUMENTS`:
52
- - Project key: build JQL `project = <KEY> AND Status = "Ready" ORDER BY priority DESC, created ASC`.
53
- - Full JQL: use as-is. If it does not include a `Status` clause, append `AND Status = "Ready"`.
54
- 2. Resolve Atlassian cloud ID via `getAccessibleAtlassianResources`.
109
+ - Project key: build JQL `project = <KEY> AND Status = "$READY" ORDER BY priority DESC, created ASC`.
110
+ - Full JQL: use as-is. If it does not include a `Status` clause, append `AND Status = "$READY"`.
111
+ 2. Confirm the configured Atlassian site by invoking `lisa:atlassian-access` `operation: list-sites` (it enforces connection match against `.lisa.config.json`).
55
112
 
56
- ### Phase 2 — Find Ready tickets
113
+ ### Phase 2 — Find ready tickets
57
114
 
58
- Run the JQL via `searchJiraIssuesUsingJql`. Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), labels, components.
115
+ Invoke `lisa:atlassian-access` `operation: search-issues jql: "<JQL>"`. Capture each ticket's: key, summary, issue type, priority, assignee, parent (epic), labels, components.
59
116
 
60
- If empty, report `"No tickets with Status=Ready. Nothing to do."` and exit. This is the common idle case.
117
+ If empty, report `"No tickets with Status=$READY. Nothing to do."` and exit. This is the common idle case.
61
118
 
62
- ### Phase 3 — Process each Ready ticket (serial)
119
+ ### Phase 3 — Process each ready ticket (serial)
63
120
 
64
121
  #### 3a. Claim
65
122
 
66
- Transition the ticket from `Ready` to `In Progress` via `transitionJiraIssue`.
67
- - Use `getTransitionsForJiraIssue` to find the transition ID for `In Progress`.
68
- - Post a `[claude-build-intake]` comment via `addCommentToJiraIssue`: `"Claimed by Claude. Starting build."`
69
- - This is the idempotency lock — a re-entrant cycle's `Status = Ready` filter will not see this ticket again.
123
+ Transition the ticket from `$READY` to `$CLAIMED` by invoking `lisa:atlassian-access` `operation: transition key: <TICKET> to: "$CLAIMED"`.
124
+ - Post a `[claude-build-intake]` comment via `lisa:atlassian-access` `operation: comment key: <TICKET> body: "Claimed by Claude. Starting build."`
125
+ - This is the idempotency lock — a re-entrant cycle's `Status = $READY` filter will not see this ticket again.
70
126
 
71
127
  If the transition fails (permission, missing transition, race), log under "Errors" in the cycle summary and skip this ticket. **Do not invoke the build flow on a ticket you didn't successfully claim.**
72
128
 
@@ -83,21 +139,21 @@ Invoke the `lisa:jira-agent` (existing per-ticket lifecycle agent) with the tick
83
139
  Wait for `lisa:jira-agent` to return. Capture its outcome:
84
140
  - **Success** — PR is ready (open or merged); evidence posted; ready for next status.
85
141
  - **Blocked by jira-verify pre-flight gate** — `lisa:jira-agent` itself transitions the ticket to `Blocked` and reassigns to Reporter. This is correct and expected — let it stand. Record the outcome and move on.
86
- - **Blocked by ticket-triage ambiguities** — `lisa:jira-agent` posts findings and stops. The ticket stays in `In Progress`. Surface to human; do not auto-transition. Record under "Errors" with reason `"Triage found ambiguities — see comments on <ticket-key>"`.
87
- - **Errored** — exception, missing config, etc. Leave the ticket in `In Progress` for human investigation. Record under "Errors" with the exception summary.
142
+ - **Blocked by ticket-triage ambiguities** — `lisa:jira-agent` posts findings and stops. The ticket stays in `$CLAIMED`. Surface to human; do not auto-transition. Record under "Errors" with reason `"Triage found ambiguities — see comments on <ticket-key>"`.
143
+ - **Errored** — exception, missing config, etc. Leave the ticket in `$CLAIMED` for human investigation. Record under "Errors" with the exception summary.
88
144
 
89
- #### 3c. Transition to On Dev (only on Success)
145
+ #### 3c. Transition to $DONE (only on Success)
90
146
 
91
147
  If `lisa:jira-agent` returned Success:
92
- 1. Use `getTransitionsForJiraIssue` to find the transition ID for `On Dev` (or the configured next-after-build status).
93
- 2. Transition via `transitionJiraIssue`.
94
- 3. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL>. Transitioned to On Dev."`
148
+ 1. Resolve `$DONE` for this ticket's PR base branch using the Workflow resolution algorithm above. If env can't be resolved and `done` is env-keyed, record an Error and skip this transition — never guess.
149
+ 2. Invoke `lisa:atlassian-access` `operation: transition key: <TICKET> to: "$DONE"`.
150
+ 3. Post a `[claude-build-intake]` comment via `lisa:atlassian-access` `operation: comment key: <TICKET> body: "Build complete. PR <URL>. Transitioned to $DONE."`
95
151
 
96
- For any non-Success outcome, do NOT transition. The ticket sits in `In Progress` (or wherever `lisa:jira-agent` left it for the Blocked case) — the cycle's job is done; humans take it from there.
152
+ For any non-Success outcome, do NOT transition. The ticket sits in `$CLAIMED` (or wherever `lisa:jira-agent` left it for the Blocked case) — the cycle's job is done; humans take it from there.
97
153
 
98
154
  #### 3d. Continue
99
155
 
100
- Move to the next Ready ticket. One ticket failing does not stop others.
156
+ Move to the next ready ticket. One ticket failing does not stop others.
101
157
 
102
158
  ### Phase 4 — Summary report
103
159
 
@@ -109,7 +165,7 @@ Cycle started: <ISO timestamp>
109
165
  Cycle completed: <ISO timestamp>
110
166
 
111
167
  Tickets processed: <n>
112
- - On Dev (build complete, PR ready): <n>
168
+ - $DONE (build complete, PR ready): <n>
113
169
  - <ticket-key> <summary> → PR <URL>
114
170
  - Blocked (pre-flight verify failed): <n>
115
171
  - <ticket-key> <summary> — see ticket comments
@@ -123,32 +179,41 @@ Total PRs opened: <n>
123
179
 
124
180
  ## Idempotency & safety
125
181
 
126
- - **Claim-first ordering**: `In Progress` set BEFORE `lisa:jira-agent` invocation — no double-pickup.
127
- - **No writes outside the lifecycle**: this skill only transitions `ReadyIn Progress` and `In Progress On Dev`. Every other status change is owned by `lisa:jira-agent` (which suggests transitions but only auto-transitions on the verify-FAIL path).
182
+ - **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:jira-agent` invocation — no double-pickup.
183
+ - **No writes outside the lifecycle**: this skill only transitions `$READY$CLAIMED` and `$CLAIMED$DONE`. Every other status change is owned by `lisa:jira-agent` (which suggests transitions but only auto-transitions on the verify-FAIL path).
128
184
  - **Failure isolation**: per-ticket exceptions caught and recorded; the cycle continues.
129
185
  - **Single cycle per query**: do not run two `lisa:jira-build-intake` cycles in parallel against overlapping queries — concurrent claims could race. The scheduling layer (when added) is responsible for serialization.
130
- - **Never invent a transition**: if `In Progress` or `On Dev` aren't valid transitions in the project's workflow, stop and report rather than guessing alternative names.
186
+ - **Never invent a transition**: if `$CLAIMED` or `$DONE` aren't valid transitions in the project's workflow, stop and report rather than guessing alternative names.
131
187
 
132
188
  ## Configuration
133
189
 
134
- Reads `atlassian.cloudId` and `jira.project` from `.lisa.config.json` (with `.lisa.config.local.json` overriding per key). The project key is also accepted as `$ARGUMENTS` for ad-hoc invocations.
190
+ Reads `atlassian.cloudId`, `jira.project`, and `jira.workflow.{ready,claimed,done}` from `.lisa.config.json` (with `.lisa.config.local.json` overriding per key). The project key is also accepted as `$ARGUMENTS` for ad-hoc invocations.
191
+
192
+ Status role names default to:
193
+ - `ready` → `"Ready"`
194
+ - `claimed` → `"In Progress"`
195
+ - `done` → env-keyed map `{ "dev": "On Dev", "staging": "On Stg", "production": "Done" }`
196
+
197
+ If a project uses different names (e.g. `Open` instead of `TODO`, `In Development` instead of `In Progress`, `Code Review` for terminal), override the relevant key in `.lisa.config.json` `jira.workflow.*`. The setup skills (`/lisa:setup:jira`) handle this interactively.
135
198
 
136
- Status names default to `Ready`, `In Progress`, `On Dev`. If a project uses different names (`Open` instead of `TODO`, `In Development` instead of `In Progress`, `Code Review` instead of `On Dev`), pass overrides in `$ARGUMENTS` as `claim_status="In Development" done_status="Code Review"`.
199
+ Per-invocation overrides via `$ARGUMENTS` (e.g. `claim_status="In Development"`) are accepted as a secondary escape hatch but `.lisa.config.json` is the canonical source.
137
200
 
138
- If a `Ready` status does not exist in the JIRA project's workflow, this skill cannot run. The remediation is to add `Ready` to the project workflow scheme — JIRA admin task, not something this skill can do.
201
+ If a ready-equivalent status does not exist in the JIRA project's workflow, this skill cannot run. The remediation is to add it to the project workflow scheme — JIRA admin task, not something this skill can do.
139
202
 
140
203
  | Field / variable | Default | Purpose |
141
204
  |------------------|---------|---------|
142
205
  | `.lisa.config.json` `jira.project` | (from `$ARGUMENTS`) | Project key for the default JQL |
143
206
  | `.lisa.config.json` `atlassian.cloudId` | — | Atlassian Cloud site UUID (required) |
144
- | Status: queue | `Ready` | The status that signals "human says this is buildable" |
145
- | Status: claim | `In Progress` | The intermediate status the agent sets on pickup |
146
- | Status: done | `On Dev` | The status set after a successful build |
207
+ | `.lisa.config.json` `jira.workflow.ready` | `Ready` | The status that signals "human says this is buildable" |
208
+ | `.lisa.config.json` `jira.workflow.claimed` | `In Progress` | The intermediate status the agent sets on pickup |
209
+ | `.lisa.config.json` `jira.workflow.done` | env-keyed map (`dev`/`staging`/`production`) or string | The status set after a successful build; env-aware |
210
+ | `.lisa.config.json` `deploy.branches` | — | Reverse-lookup map for env inference from PR base branch |
147
211
 
148
212
  ## Rules
149
213
 
150
- - Never transition a ticket the cycle didn't claim. The `In Progress` transition is the signature of cycle ownership.
214
+ - Never transition a ticket the cycle didn't claim. The `$CLAIMED` transition is the signature of cycle ownership.
151
215
  - Never bypass `lisa:jira-agent` to do build work directly. `lisa:jira-agent` owns the per-ticket lifecycle (read, verify, triage, route, sync, evidence). This skill is the dispatcher, not the builder.
152
- - Never auto-transition past `On Dev`. Downstream statuses (`On QA`, `Done`) are owned by QA / product / a future verification-intake skill — not this one.
216
+ - Never auto-transition past `$DONE`. Downstream statuses are owned by QA / product / a future verification-intake skill — not this one.
153
217
  - If the ticket has no Validation Journey or no sign-in credentials in its description, `lisa:jira-agent`'s pre-flight verify will catch it and transition to `Blocked` — **don't try to fix the ticket from here**. Pre-flight gating is `lisa:jira-agent`'s job; running build work on a thin ticket produces broken work.
154
218
  - On any unexpected response from `lisa:jira-agent` (status it doesn't claim, missing PR URL on success, etc.), record as Error and surface — never assume.
219
+ - Never pick an arbitrary env for `$DONE` resolution. If `done` is a map and env is ambiguous, fail loudly.
@@ -1,12 +1,14 @@
1
1
  ---
2
2
  name: jira-create
3
3
  description: This skill should be used when creating JIRA epics, stories, and tasks from code files or descriptions. It analyzes the provided input, determines the appropriate issue hierarchy, and creates issues with comprehensive quality requirements including test-first development and documentation.
4
- allowed-tools: ["Read", "Glob", "LS", "Skill", "mcp__atlassian__getVisibleJiraProjects", "mcp__atlassian__getJiraProjectIssueTypesMetadata", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Read", "Glob", "LS", "Skill"]
5
5
  ---
6
6
 
7
7
  # Create JIRA Issues from $ARGUMENTS
8
8
 
9
- Analyze the provided file(s) and plan a JIRA hierarchy. **This skill plans structure only — every individual ticket write is delegated to `lisa:jira-write-ticket`.** Do not call `mcp__atlassian__createJiraIssue` from this skill; the necessary write tools are intentionally not in `allowed-tools`.
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
10
+
11
+ Analyze the provided file(s) and plan a JIRA hierarchy. **This skill plans structure only — every individual ticket write is delegated to `lisa:jira-write-ticket`.** Do not invoke `lisa:atlassian-access` write operations directly from this skill — all writes go through `lisa:jira-write-ticket`.
10
12
 
11
13
  ## Process
12
14
 
@@ -110,7 +112,7 @@ Exclude unless requested: migration plans, performance tests
110
112
 
111
113
  ## Delegation to jira-write-ticket
112
114
 
113
- **Mandatory.** Every ticket created by this skill MUST go through `lisa:jira-write-ticket`. This skill never calls `mcp__atlassian__createJiraIssue` itself — that tool is intentionally excluded from `allowed-tools` so the gate cannot be bypassed.
115
+ **Mandatory.** Every ticket created by this skill MUST go through `lisa:jira-write-ticket`. This skill never invokes `lisa:atlassian-access` write operations itself — all writes are delegated so the gate cannot be bypassed.
114
116
 
115
117
  `lisa:jira-write-ticket` enforces things this skill does not, and which determine ticket quality:
116
118
  - 3-audience description (Context / Technical Approach / Acceptance Criteria)
@@ -1,10 +1,27 @@
1
1
  ---
2
2
  name: jira-evidence
3
- description: "Upload text evidence to GitHub pr-assets release, update PR description, post JIRA comment with code blocks, and move ticket to Code Review. Reusable by any skill that captures evidence and generates evidence/comment.txt + evidence/comment.md."
3
+ description: "Upload text evidence to GitHub pr-assets release, update PR description, post JIRA comment with code blocks, and move ticket to the configured code-review status. Reusable by any skill that captures evidence and generates evidence/comment.txt + evidence/comment.md."
4
4
  ---
5
5
 
6
6
  # JIRA Evidence Posting
7
7
 
8
+ ## Workflow resolution
9
+
10
+ The post-build review status is read from `.lisa.config.json` `jira.workflow.review` (or `jira.workflow.code_review`), falling back to `Code Review`. JIRA does not have a separate `review` role in the canonical config schema (the build lifecycle stays in `claimed` until `done`); this skill uses the project's actual post-build review status when one exists. If the configured status is not a valid transition from the ticket's current state, log a warning and skip the transition — the human will handle it.
11
+
12
+ ```bash
13
+ REVIEW="Code Review"
14
+ if [ -f .lisa.config.json ]; then
15
+ _cfg=$(jq -r '.jira.workflow.review // .jira.workflow.code_review // empty' .lisa.config.json 2>/dev/null)
16
+ [ -n "$_cfg" ] && REVIEW="$_cfg"
17
+ fi
18
+ if [ -f .lisa.config.local.json ]; then
19
+ _local=$(jq -r '.jira.workflow.review // .jira.workflow.code_review // empty' .lisa.config.local.json 2>/dev/null)
20
+ [ -n "$_local" ] && REVIEW="$_local"
21
+ fi
22
+ ```
23
+
24
+
8
25
  Upload captured evidence and generated templates to GitHub PR description and JIRA ticket. This skill is the posting step — it assumes evidence files and comment templates already exist in the evidence directory.
9
26
 
10
27
  ## Arguments
@@ -43,7 +60,7 @@ bash .claude/skills/jira-evidence/scripts/post-evidence.sh PROJ-123 ./evidence 4
43
60
  2. **Upload to GitHub `pr-assets` release** — Uploads evidence files via `gh release upload --clobber`
44
61
  3. **Update PR description** — Replaces or appends the `## Evidence` section in the PR body
45
62
  4. **Post JIRA comment** — Posts `comment.txt` as a new comment (wiki markup with code blocks)
46
- 5. **Move ticket to Code Review** — Transitions the JIRA ticket
63
+ 5. **Move ticket to the configured review status** — Transitions the JIRA ticket to `$REVIEW` (default: `Code Review`).
47
64
 
48
65
  ## Evidence Naming Convention
49
66
 
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  name: jira-journey
3
3
  description: "Parse a JIRA ticket's Validation Journey section, execute the verification steps using appropriate tools (curl, test commands, database queries), capture evidence, and post to JIRA + GitHub PR using the jira-evidence skill."
4
- allowed-tools: ["Bash", "Read", "Glob", "Grep", "Skill", "mcp__atlassian__getJiraIssue", "mcp__atlassian__updateJiraIssue"]
4
+ allowed-tools: ["Bash", "Read", "Glob", "Grep", "Skill"]
5
5
  ---
6
6
 
7
7
  # JIRA Validation Journey (TypeScript)
8
8
 
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly. Note: the helper scripts (`scripts/parse-plan.py`, `scripts/jira-evidence/post-evidence.sh`) currently use direct API calls and are pending migration to route through `atlassian-access`.
10
+
9
11
  Parse a JIRA ticket's Validation Journey, execute the verification steps using the appropriate tools for the change type, capture evidence at each `[EVIDENCE: name]` marker, and post to JIRA + GitHub PR.
10
12
 
11
13
  ## Arguments
@@ -1,23 +1,25 @@
1
1
  ---
2
2
  name: jira-read-ticket
3
3
  description: "Fetches the full scope of a JIRA ticket — metadata, description, acceptance criteria, all comments, remote links (PRs, Confluence, dashboards), issue links (blocks/is blocked by/relates to/duplicates/clones), epic parent with siblings, and subtasks. Produces a consolidated context bundle that downstream agents consume so they never act on a single ticket in isolation."
4
- allowed-tools: ["Bash", "mcp__atlassian__getJiraIssue", "mcp__atlassian__getJiraIssueRemoteIssueLinks", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Bash", "Skill"]
5
5
  ---
6
6
 
7
7
  # Read JIRA Ticket: $ARGUMENTS
8
8
 
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
10
+
9
11
  Fetch the full scope of the ticket AND its related graph. Downstream agents must never act on a ticket in isolation — always call this skill first so they see blockers, epic siblings, linked PRs, and historical comments.
10
12
 
11
13
  Repository name for scoped comments and logs: `basename $(git rev-parse --show-toplevel)`.
12
14
 
13
15
  ## Phase 1 — Resolve Context
14
16
 
15
- 1. Call `mcp__atlassian__getAccessibleAtlassianResources` to get the cloud ID.
17
+ 1. Invoke `lisa:atlassian-access` via the Skill tool with `operation: list-sites` to confirm the configured site is reachable and resolve the cloud ID.
16
18
  2. If $ARGUMENTS is not a ticket key (e.g. `PROJ-123`), stop and report. Do NOT guess.
17
19
 
18
20
  ## Phase 2 — Fetch Primary Ticket
19
21
 
20
- Call `mcp__atlassian__getJiraIssue` for the target ticket. Extract and preserve:
22
+ Invoke `lisa:atlassian-access` via the Skill tool with `operation: read-ticket key: <TICKET-KEY>` for the target ticket. Extract and preserve:
21
23
 
22
24
  ### Metadata
23
25
 
@@ -60,7 +62,7 @@ Fetch ALL comments in chronological order. Do not truncate. For each:
60
62
 
61
63
  ## Phase 3 — Fetch Remote Links
62
64
 
63
- Call `mcp__atlassian__getJiraIssueRemoteIssueLinks`. For each remote link:
65
+ The primary ticket payload returned by `lisa:atlassian-access` `operation: read-ticket` includes the issue's remote links. If the substrate returns remote links separately, request them via `lisa:atlassian-access` with `operation: read-ticket key: <K>` (the operation MUST return remote links — extend `atlassian-access` if it doesn't). For each remote link:
64
66
 
65
67
  - **GitHub PR or commit** (`github.com/.../(pull|commit)/...`): run `gh pr view <url> --json title,state,body,mergedAt,reviewDecision,comments,reviews` (for PRs) or `gh api repos/<owner>/<repo>/commits/<sha>` (for commits). Capture title, state, body, unresolved review comments, merge status.
66
68
  - **Confluence page**: capture title and URL. Do not fetch body unless a downstream task explicitly needs it.
@@ -78,7 +80,7 @@ Every linked ticket must be fetched. Do not skip any link type. For each link in
78
80
  - `clones` / `is cloned by`
79
81
  - Any other custom link types configured in the project
80
82
 
81
- For each linked ticket, call `mcp__atlassian__getJiraIssue` and capture:
83
+ For each linked ticket, invoke `lisa:atlassian-access` with `operation: read-ticket key: <LINKED-KEY>` and capture:
82
84
 
83
85
  - Key, summary, type, status, resolution
84
86
  - Description (full, unless closed with resolution `Won't Do`/`Duplicate` — then summary only)
@@ -92,19 +94,19 @@ For each linked ticket, call `mcp__atlassian__getJiraIssue` and capture:
92
94
 
93
95
  If the primary ticket has an epic parent (or IS an epic):
94
96
 
95
- 1. Fetch the epic itself via `mcp__atlassian__getJiraIssue` — full description, acceptance criteria, all comments, Validation Journey.
97
+ 1. Fetch the epic itself via `lisa:atlassian-access` `operation: read-ticket key: <EPIC-KEY>` — full description, acceptance criteria, all comments, Validation Journey.
96
98
  2. Find epic siblings via JQL:
97
99
  ```jql
98
100
  "Epic Link" = <EPIC-KEY> AND key != <TICKET-KEY>
99
101
  ```
100
- Use `mcp__atlassian__searchJiraIssuesUsingJql`. For each sibling capture: key, summary, type, status, assignee, priority.
102
+ Invoke `lisa:atlassian-access` with `operation: search-issues jql: "<above-JQL>"`. For each sibling capture: key, summary, type, status, assignee, priority.
101
103
  3. Read each sibling's description at a SUMMARY level (first paragraph only) — the goal is to surface related in-flight work, not duplicate full content. If a sibling is `In Progress` or `In Review` with an assignee different from the current ticket, flag it prominently.
102
104
 
103
105
  If the primary ticket IS an epic, also fetch all children via the JQL above.
104
106
 
105
107
  ## Phase 6 — Fetch Subtasks
106
108
 
107
- If the primary ticket has subtasks, fetch each via `mcp__atlassian__getJiraIssue`: key, summary, type, status, assignee, description (first paragraph), acceptance criteria.
109
+ If the primary ticket has subtasks, fetch each via `lisa:atlassian-access` `operation: read-ticket key: <SUBTASK-KEY>`: key, summary, type, status, assignee, description (first paragraph), acceptance criteria.
108
110
 
109
111
  ## Phase 7 — Assemble Context Bundle
110
112
 
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  name: jira-sync
3
3
  description: "Syncs plan progress to a linked JIRA ticket. Posts plan contents, progress updates, branch links, and PR links at key milestones. Use this skill throughout the plan lifecycle to keep tickets in sync."
4
- allowed-tools: ["mcp__atlassian__*", "Bash", "Read", "Glob", "Grep"]
4
+ allowed-tools: ["Skill", "Bash", "Read", "Glob", "Grep"]
5
5
  ---
6
6
 
7
7
  # JIRA Ticket Sync
8
8
 
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
10
+
9
11
  Sync current plan progress to JIRA ticket: $ARGUMENTS
10
12
 
11
13
  If no argument provided, search for a ticket URL in the active plan file (most recently modified `.md` in `plans/`).
@@ -15,7 +17,7 @@ If no argument provided, search for a ticket URL in the active plan file (most r
15
17
  ### Step 1: Identify Ticket and Context
16
18
 
17
19
  1. **Parse ticket ID** from `$ARGUMENTS` or extract from the active plan file
18
- 2. **Fetch current ticket state** via JIRA MCP (`mcp__atlassian__getJiraIssue`)
20
+ 2. **Fetch current ticket state** by invoking `lisa:atlassian-access` via the Skill tool with `operation: read-ticket key: <TICKET-ID>`
19
21
  3. **Determine current milestone** by checking:
20
22
  - Does a plan file exist? → Plan created
21
23
  - Is there a working branch? → Implementation started
@@ -36,11 +38,15 @@ Based on the current milestone:
36
38
 
37
39
  ### Step 3: Post Update
38
40
 
39
- 1. **Add a comment** to the ticket with the gathered content via JIRA MCP
40
- 2. **Update ticket fields** if applicable:
41
+ Before adding a comment, check for an existing milestone comment to avoid duplicates (idempotency):
42
+
43
+ 1. **Fetch existing comments** by invoking `lisa:atlassian-access` with `operation: search-issues jql: "..."` or by reading the ticket's comments. Look for a comment whose body contains a stable milestone marker (e.g., the heading `## Plan Created`, `## Implementation in Progress`, `## PR Ready`, or `## PR Merged`) that matches the current milestone.
44
+ 2. **If a matching comment already exists**, skip posting and proceed to field updates — idempotent re-runs must not create duplicates.
45
+ 3. **If no matching comment exists**, add a new comment by invoking `lisa:atlassian-access` with `operation: comment key: <TICKET-ID> body: "..."`.
46
+ 4. **Update ticket fields** if applicable:
41
47
  - Add branch name to a custom field or comment
42
48
  - Add PR link to a custom field or comment
43
- 3. **Report** what was synced to the user
49
+ 5. **Report** what was synced to the user
44
50
 
45
51
  ### Step 4: Suggest Status Transition
46
52
 
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  name: jira-validate-ticket
3
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-tracker 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"]
4
+ allowed-tools: ["Bash", "Skill"]
5
5
  ---
6
6
 
7
7
  # Validate JIRA Ticket: $ARGUMENTS
8
8
 
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
10
+
9
11
  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 (`lisa:jira-write-ticket` for pre-write gating, `lisa:notion-to-tracker` for PRD dry-run, `lisa:jira-verify` for post-write checks).
10
12
 
11
13
  ## Input
@@ -60,7 +62,7 @@ links: [{ key: "PROJ-99", type: "is blocked by" }] # known issue links (may be
60
62
  remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
61
63
  ```
62
64
 
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.
65
+ If the caller passes only a ticket key, fetch the ticket via `lisa:atlassian-access` `operation: read-ticket key: <KEY>`, derive the same fields from the fetched data, then run gates.
64
66
 
65
67
  ## Gates
66
68
 
@@ -83,6 +85,7 @@ Each gate is tagged with a fixed `category` and a `product_relevant` boolean. Ca
83
85
  | S11 Validation Journey | `acceptance-criteria` | true |
84
86
  | S12 Source Precedence | `design-ux` | true |
85
87
  | S13 Relationship Search | `dependency` | true |
88
+ | S14 Evidence manifest binding (leaf work units) | `acceptance-criteria` | true |
86
89
  | F1 Issue type valid in project | `structural` | false |
87
90
  | F2 Epic parent exists and is an Epic | `structural` | false |
88
91
  | F3 Linked tickets exist | `structural` | false |
@@ -188,28 +191,36 @@ The ticket must EITHER have at least one issue link in `links`, OR the descripti
188
191
 
189
192
  A ticket with zero links and no documented search: FAIL.
190
193
 
194
+ #### S14 — Evidence manifest binding (leaf work units)
195
+
196
+ When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND `runtime_behavior_change = true`, the `h2. Validation Journey` must declare at least one `[EVIDENCE: name]` marker. Each marker name must be kebab-case and unique within the ticket. These markers are the work unit's **evidence manifest** — the exact, enumerated set of artifacts that must be captured and attached before the ticket may be marked complete (see the "Per-Work-Unit Evidence Contract" section of the `verification` rule, the Definition of Done in `verification-lifecycle`, and the evidence-manifest gate in `tracker-evidence`).
197
+
198
+ FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]` markers, or when any marker name is empty, duplicated, or not kebab-case. A behavior-changing work unit SHOULD declare both a success marker and an error/edge marker; a journey with only one marker passes but the remediation should recommend adding the error/edge case.
199
+
200
+ This gate depends on S11. It is `N/A` for Epic / Story / Spike (coordination containers, not work units) and for leaf units with `runtime_behavior_change = false` (doc-only / config-only / type-only). If S11 fails because the Validation Journey is absent, S14 also FAILs (there is no manifest to bind) with remediation pointing back to `lisa:jira-add-journey`.
201
+
191
202
  ### Feasibility Gates (require JIRA lookups; skip in dry-run if requested)
192
203
 
193
204
  #### F1 — Issue type valid in project
194
205
 
195
- Call `mcp__atlassian__getJiraProjectIssueTypesMetadata` and confirm `issue_type` exists in `project_key`.
206
+ Invoke `lisa:atlassian-access` to fetch issue-type metadata for `project_key` and confirm `issue_type` exists.
196
207
 
197
208
  #### F2 — Epic parent exists and is an Epic
198
209
 
199
- 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.
210
+ When `parent_key` is set for non-Sub-task: fetch via `lisa:atlassian-access` `operation: read-ticket key: <parent_key>`, confirm the issue type is `Epic`. For Sub-task, confirm the parent is a non-Sub-task in the same project.
200
211
 
201
212
  #### F3 — Linked tickets exist
202
213
 
203
- For each entry in `links`, call `mcp__atlassian__getJiraIssue` to confirm the key resolves. Flag broken keys.
214
+ For each entry in `links`, invoke `lisa:atlassian-access` `operation: read-ticket key: <link.key>` to confirm the key resolves. Flag broken keys.
204
215
 
205
216
  #### F4 — Required custom fields populated
206
217
 
207
- `mcp__atlassian__getJiraProjectIssueTypesMetadata` returns required custom fields for the issue type. Any required custom field not provided in the spec: FAIL.
218
+ Use the same project-issue-type-metadata lookup from F1 (via `lisa:atlassian-access`) to learn required custom fields for the issue type. Any required custom field not provided in the spec: FAIL.
208
219
 
209
220
  ## Execution
210
221
 
211
- 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.
212
- 2. Resolve cloud ID via `mcp__atlassian__getAccessibleAtlassianResources` if any feasibility gate will run.
222
+ 1. Parse `$ARGUMENTS`. If it's a ticket key, fetch the ticket via `lisa:atlassian-access` `operation: read-ticket` and derive the spec from the fetched fields. Otherwise parse the YAML spec.
223
+ 2. If any feasibility gate will run, invoke `lisa:atlassian-access` `operation: list-sites` once to confirm the configured site is reachable (it enforces connection match against `.lisa.config.json`).
213
224
  3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
214
225
  4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
215
226
  5. Emit the report below.
@@ -235,6 +246,7 @@ Output is a single fenced text block. Callers parse it; do not add free-form pro
235
246
  - [PASS|FAIL|N/A] S11 Validation Journey — <one-line reason>
236
247
  - [PASS|FAIL|N/A] S12 Source Precedence — <one-line reason>
237
248
  - [PASS|FAIL|N/A] S13 Relationship Search — <one-line reason>
249
+ - [PASS|FAIL|N/A] S14 Evidence manifest binding — <one-line reason>
238
250
 
239
251
  ### Feasibility Gates (omit this section when --spec-only)
240
252
  - [PASS|FAIL|N/A] F1 Issue type valid in project — <one-line reason>
@@ -259,7 +271,7 @@ The verdict is `PASS` if and only if every applicable gate is `PASS`. Any `FAIL`
259
271
 
260
272
  ### Failure-detail fields
261
273
 
262
- - **gate**: the gate ID (`S1`–`S13`, `F1`–`F4`).
274
+ - **gate**: the gate ID (`S1`–`S14`, `F1`–`F4`).
263
275
  - **category**: the gate's fixed category from the table above. Callers use this to label or filter comments — `product-clarity`, `acceptance-criteria`, `design-ux`, `scope`, `dependency`, `data`, `technical`, or `structural`.
264
276
  - **product_relevant**: matches the gate's table entry. `false` means the failure is an internal data-quality problem (e.g., the agent built a malformed spec, an issue type is invalid in the project) and the caller should fix it without bothering the product team. `true` means the PRD needs product input to resolve.
265
277
  - **what**: plain-language description of the issue. No gate IDs, no JIRA jargon, no engineering shorthand. A product owner reading this on a Notion comment should understand what is unclear and why.
@@ -267,7 +279,7 @@ The verdict is `PASS` if and only if every applicable gate is `PASS`. Any `FAIL`
267
279
 
268
280
  ## Rules
269
281
 
270
- - Never write to JIRA. The `allowed-tools` list intentionally excludes `createJiraIssue`, `editJiraIssue`, `createIssueLink`, `addCommentToJiraIssue`.
282
+ - Never write to JIRA. This skill only invokes `lisa:atlassian-access` with read-only operations (`read-ticket`, `search-issues`, `list-sites`); it never calls write operations (`write-ticket`, `transition`, `comment`, `link`).
271
283
  - Never auto-fix the spec. This skill reports gaps; callers decide what to do (block, ask the human, regenerate the spec).
272
284
  - Never silently skip a gate. If a gate genuinely doesn't apply, return `N/A` with the reason; never omit it.
273
285
  - The `what` and `recommendation` fields must be concrete and product-readable — the dry-run path turns each failure into a Notion comment, and the audience for those comments is the product team, not engineers. Vague guidance ("clarify this", "decide how to handle X") is useless; always give 1–3 candidate resolutions.
@@ -1,19 +1,21 @@
1
1
  ---
2
2
  name: jira-verify
3
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"]
4
+ allowed-tools: ["Skill"]
5
5
  ---
6
6
 
7
7
  # Verify JIRA Ticket: $ARGUMENTS
8
8
 
9
+ All Atlassian operations in this skill go through `lisa:atlassian-access`. Do not call MCP tools or `acli` directly.
10
+
9
11
  Verify that the existing JIRA ticket `$ARGUMENTS` meets organizational standards. This skill is a thin post-write wrapper around `lisa:jira-validate-ticket`: it fetches the live ticket and asks `lisa:jira-validate-ticket` to run the gates against the fetched state.
10
12
 
11
13
  This indirection exists so the gate definitions live in exactly one place (`lisa:jira-validate-ticket`). When the bar changes, change it there — `lisa:jira-verify`, `lisa:jira-write-ticket` (Phase 5.5 pre-write), and `lisa:notion-to-tracker` (PRD dry-run) all pick it up.
12
14
 
13
15
  ## Process
14
16
 
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
+ 1. Invoke `lisa:atlassian-access` via the Skill tool with `operation: list-sites` to confirm the configured site is reachable (the access skill enforces connection match against `.lisa.config.json`).
18
+ 2. Fetch the ticket via `lisa:atlassian-access` `operation: read-ticket key: $ARGUMENTS`. Pull issue type, summary, description, parent, links, labels, components, and any custom fields needed.
17
19
  3. Invoke `lisa: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
20
  4. Surface the validator's report verbatim to the caller.
19
21