@codyswann/lisa 2.21.0 → 2.23.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 (124) 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/linear-agent.md +15 -9
  11. package/plugins/lisa/agents/linear-build-intake.md +13 -11
  12. package/plugins/lisa/agents/linear-prd-intake.md +11 -9
  13. package/plugins/lisa/agents/notion-prd-intake.md +11 -9
  14. package/plugins/lisa/commands/setup/atlassian.md +7 -0
  15. package/plugins/lisa/commands/setup/confluence.md +7 -0
  16. package/plugins/lisa/commands/setup/jira.md +7 -0
  17. package/plugins/lisa/commands/setup/notion.md +7 -0
  18. package/plugins/lisa/rules/base-rules.md +2 -2
  19. package/plugins/lisa/rules/config-resolution.md +242 -24
  20. package/plugins/lisa/rules/repo-scope-split.md +41 -0
  21. package/plugins/lisa/rules/verification.md +13 -0
  22. package/plugins/lisa/skills/atlassian-access/SKILL.md +260 -0
  23. package/plugins/lisa/skills/confluence-prd-intake/SKILL.md +167 -82
  24. package/plugins/lisa/skills/confluence-to-tracker/SKILL.md +39 -26
  25. package/plugins/lisa/skills/git-submit-pr/SKILL.md +1 -1
  26. package/plugins/lisa/skills/github-add-journey/SKILL.md +1 -0
  27. package/plugins/lisa/skills/github-build-intake/SKILL.md +104 -40
  28. package/plugins/lisa/skills/github-evidence/SKILL.md +22 -5
  29. package/plugins/lisa/skills/github-prd-intake/SKILL.md +87 -51
  30. package/plugins/lisa/skills/github-to-tracker/SKILL.md +2 -2
  31. package/plugins/lisa/skills/github-validate-issue/SKILL.md +11 -1
  32. package/plugins/lisa/skills/jira-add-journey/SKILL.md +1 -0
  33. package/plugins/lisa/skills/jira-build-intake/SKILL.md +110 -45
  34. package/plugins/lisa/skills/jira-create/SKILL.md +5 -3
  35. package/plugins/lisa/skills/jira-evidence/SKILL.md +19 -2
  36. package/plugins/lisa/skills/jira-journey/SKILL.md +3 -1
  37. package/plugins/lisa/skills/jira-read-ticket/SKILL.md +10 -8
  38. package/plugins/lisa/skills/jira-sync/SKILL.md +11 -5
  39. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +22 -10
  40. package/plugins/lisa/skills/jira-verify/SKILL.md +5 -3
  41. package/plugins/lisa/skills/jira-write-ticket/SKILL.md +16 -14
  42. package/plugins/lisa/skills/linear-add-journey/SKILL.md +1 -0
  43. package/plugins/lisa/skills/linear-build-intake/SKILL.md +90 -32
  44. package/plugins/lisa/skills/linear-evidence/SKILL.md +22 -5
  45. package/plugins/lisa/skills/linear-prd-intake/SKILL.md +92 -57
  46. package/plugins/lisa/skills/linear-validate-issue/SKILL.md +10 -0
  47. package/plugins/lisa/skills/notion-access/SKILL.md +193 -0
  48. package/plugins/lisa/skills/notion-prd-intake/SKILL.md +105 -46
  49. package/plugins/lisa/skills/notion-to-tracker/SKILL.md +7 -5
  50. package/plugins/lisa/skills/setup-atlassian/SKILL.md +316 -0
  51. package/plugins/lisa/skills/setup-confluence/SKILL.md +245 -0
  52. package/plugins/lisa/skills/setup-jira/SKILL.md +198 -0
  53. package/plugins/lisa/skills/setup-notion/SKILL.md +283 -0
  54. package/plugins/lisa/skills/task-decomposition/SKILL.md +2 -0
  55. package/plugins/lisa/skills/ticket-triage/SKILL.md +4 -1
  56. package/plugins/lisa/skills/tracker-evidence/SKILL.md +1 -0
  57. package/plugins/lisa/skills/verification-lifecycle/SKILL.md +2 -0
  58. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  60. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  65. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  66. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  68. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  70. package/plugins/src/base/agents/confluence-prd-intake.md +11 -9
  71. package/plugins/src/base/agents/github-agent.md +18 -10
  72. package/plugins/src/base/agents/github-build-intake.md +10 -8
  73. package/plugins/src/base/agents/github-prd-intake.md +11 -9
  74. package/plugins/src/base/agents/jira-agent.md +12 -8
  75. package/plugins/src/base/agents/jira-build-intake.md +9 -7
  76. package/plugins/src/base/agents/linear-agent.md +15 -9
  77. package/plugins/src/base/agents/linear-build-intake.md +13 -11
  78. package/plugins/src/base/agents/linear-prd-intake.md +11 -9
  79. package/plugins/src/base/agents/notion-prd-intake.md +11 -9
  80. package/plugins/src/base/commands/setup/atlassian.md +7 -0
  81. package/plugins/src/base/commands/setup/confluence.md +7 -0
  82. package/plugins/src/base/commands/setup/jira.md +7 -0
  83. package/plugins/src/base/commands/setup/notion.md +7 -0
  84. package/plugins/src/base/rules/base-rules.md +2 -2
  85. package/plugins/src/base/rules/config-resolution.md +242 -24
  86. package/plugins/src/base/rules/repo-scope-split.md +41 -0
  87. package/plugins/src/base/rules/verification.md +13 -0
  88. package/plugins/src/base/skills/atlassian-access/SKILL.md +260 -0
  89. package/plugins/src/base/skills/confluence-prd-intake/SKILL.md +167 -82
  90. package/plugins/src/base/skills/confluence-to-tracker/SKILL.md +39 -26
  91. package/plugins/src/base/skills/git-submit-pr/SKILL.md +1 -1
  92. package/plugins/src/base/skills/github-add-journey/SKILL.md +1 -0
  93. package/plugins/src/base/skills/github-build-intake/SKILL.md +104 -40
  94. package/plugins/src/base/skills/github-evidence/SKILL.md +22 -5
  95. package/plugins/src/base/skills/github-prd-intake/SKILL.md +87 -51
  96. package/plugins/src/base/skills/github-to-tracker/SKILL.md +2 -2
  97. package/plugins/src/base/skills/github-validate-issue/SKILL.md +11 -1
  98. package/plugins/src/base/skills/jira-add-journey/SKILL.md +1 -0
  99. package/plugins/src/base/skills/jira-build-intake/SKILL.md +110 -45
  100. package/plugins/src/base/skills/jira-create/SKILL.md +5 -3
  101. package/plugins/src/base/skills/jira-evidence/SKILL.md +19 -2
  102. package/plugins/src/base/skills/jira-journey/SKILL.md +3 -1
  103. package/plugins/src/base/skills/jira-read-ticket/SKILL.md +10 -8
  104. package/plugins/src/base/skills/jira-sync/SKILL.md +11 -5
  105. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +22 -10
  106. package/plugins/src/base/skills/jira-verify/SKILL.md +5 -3
  107. package/plugins/src/base/skills/jira-write-ticket/SKILL.md +16 -14
  108. package/plugins/src/base/skills/linear-add-journey/SKILL.md +1 -0
  109. package/plugins/src/base/skills/linear-build-intake/SKILL.md +90 -32
  110. package/plugins/src/base/skills/linear-evidence/SKILL.md +22 -5
  111. package/plugins/src/base/skills/linear-prd-intake/SKILL.md +92 -57
  112. package/plugins/src/base/skills/linear-validate-issue/SKILL.md +10 -0
  113. package/plugins/src/base/skills/notion-access/SKILL.md +193 -0
  114. package/plugins/src/base/skills/notion-prd-intake/SKILL.md +105 -46
  115. package/plugins/src/base/skills/notion-to-tracker/SKILL.md +7 -5
  116. package/plugins/src/base/skills/setup-atlassian/SKILL.md +316 -0
  117. package/plugins/src/base/skills/setup-confluence/SKILL.md +245 -0
  118. package/plugins/src/base/skills/setup-jira/SKILL.md +198 -0
  119. package/plugins/src/base/skills/setup-notion/SKILL.md +283 -0
  120. package/plugins/src/base/skills/task-decomposition/SKILL.md +2 -0
  121. package/plugins/src/base/skills/ticket-triage/SKILL.md +4 -1
  122. package/plugins/src/base/skills/tracker-evidence/SKILL.md +1 -0
  123. package/plugins/src/base/skills/verification-lifecycle/SKILL.md +2 -0
  124. package/scripts/check-plugins-sync.sh +45 -0
@@ -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
 
@@ -1,11 +1,13 @@
1
1
  ---
2
2
  name: jira-write-ticket
3
3
  description: "Creates or updates a JIRA ticket following organizational best practices. Enforces description quality (coding assistant / developer / stakeholder sections), Gherkin acceptance criteria, epic parent relationship, explicit link discovery (blocks / is blocked by / relates to / duplicates / clones), remote links (PRs, Confluence, dashboards), labels, components, fix version, priority, story points, and Validation Journey. Rejects thin tickets — use this skill any time a ticket is created or significantly edited."
4
- allowed-tools: ["Bash", "Skill", "mcp__atlassian__getJiraIssue", "mcp__atlassian__searchJiraIssuesUsingJql", "mcp__atlassian__createJiraIssue", "mcp__atlassian__editJiraIssue", "mcp__atlassian__createIssueLink", "mcp__atlassian__getIssueLinkTypes", "mcp__atlassian__addCommentToJiraIssue", "mcp__atlassian__getVisibleJiraProjects", "mcp__atlassian__getJiraProjectIssueTypesMetadata", "mcp__atlassian__getAccessibleAtlassianResources"]
4
+ allowed-tools: ["Bash", "Skill"]
5
5
  ---
6
6
 
7
7
  # Write 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
  Create or update a JIRA ticket with all required relationships, metadata, and quality gates. Every section below is mandatory. Thin tickets are rejected.
10
12
 
11
13
  Repository name for scoped comments: `basename $(git rev-parse --show-toplevel)`.
@@ -17,7 +19,7 @@ Determine from $ARGUMENTS and context whether this is a CREATE or UPDATE:
17
19
  - **CREATE**: no existing ticket key provided
18
20
  - **UPDATE**: ticket key provided — call `/jira-read-ticket <KEY>` first to load the full current state before editing. Never overwrite without reading.
19
21
 
20
- Resolve cloud ID via `mcp__atlassian__getAccessibleAtlassianResources`.
22
+ Resolve the active Atlassian site via `lisa:atlassian-access` `operation: list-sites` (the access skill enforces connection match against `.lisa.config.json`).
21
23
 
22
24
  ## Phase 2 — Gather Required Inputs
23
25
 
@@ -25,7 +27,7 @@ Required fields (stop and ask if missing — do not invent values):
25
27
 
26
28
  | Field | Required For | Notes |
27
29
  |-------|--------------|-------|
28
- | Project key | CREATE | Call `getVisibleJiraProjects` if unknown |
30
+ | Project key | CREATE | Resolve from `.lisa.config.json` (`jira.project`); ask the human if not configured |
29
31
  | Issue type | CREATE | Story, Task, Bug, Epic, Spike, Sub-task, Improvement |
30
32
  | Summary | CREATE, UPDATE | One line, imperative voice, under 100 chars |
31
33
  | Description | CREATE, UPDATE | Multi-section — see Phase 3 |
@@ -39,7 +41,7 @@ Required fields (stop and ask if missing — do not invent values):
39
41
 
40
42
  Optional but recommended: assignee, components, fix versions, labels, sprint, story points, reporter.
41
43
 
42
- Use `mcp__atlassian__getJiraProjectIssueTypesMetadata` to verify the issue type exists in the project and discover required custom fields.
44
+ Issue-type validity and required custom fields are enforced by `lisa:jira-validate-ticket`'s F1 / F4 gates (which run via `lisa:atlassian-access` under the hood). If you need to inspect the metadata directly, request a new operation in `atlassian-access` rather than calling MCP / acli yourself.
43
45
 
44
46
  ## Phase 3 — Description Quality
45
47
 
@@ -110,7 +112,7 @@ If the ticket is not a Bug and not an Epic, it MUST have an epic parent:
110
112
  ```jql
111
113
  project = <PROJECT> AND issuetype = Epic AND statusCategory != Done
112
114
  ```
113
- via `mcp__atlassian__searchJiraIssuesUsingJql`. Match on keywords from the summary and description.
115
+ via `lisa:atlassian-access` `operation: search-issues jql: "<query>"`. Match on keywords from the summary and description.
114
116
  3. If no epic matches, stop and ask the human to create or pick one. Do NOT orphan the ticket.
115
117
 
116
118
  ### 4b. Related Tickets
@@ -184,7 +186,7 @@ For UI-touching tickets, include the existing-component reuse expectation per `l
184
186
 
185
187
  If the ticket modifies an existing user-facing surface, a `lisa:product-walkthrough` should already have been run upstream (by `lisa:notion-to-tracker` Phase 2b or `lisa: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 `lisa:product-walkthrough` here before proceeding.
186
188
 
187
- Use Jira's web UI or `mcp__atlassian__editJiraIssue` to set the `Development` field / remote links where supported.
189
+ Use Jira's web UI or `lisa:atlassian-access` `operation: write-ticket` (UPDATE form) to set the `Development` field / remote links where supported.
188
190
 
189
191
  ## Phase 5 — Set Metadata
190
192
 
@@ -207,7 +209,7 @@ The validator is the **single source of truth** for what makes a valid ticket. T
207
209
  If the validator reports `FAIL`:
208
210
  - Surface the failure list and the per-gate remediation to the user.
209
211
  - 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.
212
+ - Never invoke `lisa:atlassian-access` with `operation: write-ticket` while the validator's verdict is FAIL.
211
213
 
212
214
  If the validator reports `PASS`, continue to Phase 6.
213
215
 
@@ -215,16 +217,16 @@ If the validator reports `PASS`, continue to Phase 6.
215
217
 
216
218
  ### CREATE
217
219
 
218
- 1. Call `mcp__atlassian__createJiraIssue` with all Phase 2/3/5 fields and the epic parent from Phase 4a.
220
+ 1. Invoke `lisa:atlassian-access` via the Skill tool with `operation: write-ticket payload: {...}` containing all Phase 2/3/5 fields and the epic parent from Phase 4a (CREATE form — no existing key).
219
221
  2. Capture the returned ticket key.
220
- 3. For each relationship from Phase 4b, call `mcp__atlassian__createIssueLink` with the correct link type (verify names via `mcp__atlassian__getIssueLinkTypes` if unsure).
221
- 4. Attach remote links from Phase 4c.
222
+ 3. For each relationship from Phase 4b, invoke `lisa:atlassian-access` with `operation: link from: <K1> to: <K2> type: "<link-type>"`. Use the exact link-type names supported by the project; surface errors if an unknown type is passed.
223
+ 4. Attach remote links from Phase 4c (via `lisa:atlassian-access` `operation: write-ticket` UPDATE form or whatever remote-link operation is dispatched).
222
224
  5. If the ticket changes runtime behavior, invoke the `lisa:jira-add-journey` skill to append the Validation Journey section.
223
225
 
224
226
  ### UPDATE
225
227
 
226
- 1. Call `mcp__atlassian__editJiraIssue` with only the fields being changed. Do NOT resend fields that weren't in the change set — it blows away history.
227
- 2. Add new relationships via `mcp__atlassian__createIssueLink`. Existing links are not touched unless explicitly removed.
228
+ 1. Invoke `lisa:atlassian-access` with `operation: write-ticket payload: {key: <K>, ...fields-being-changed}`. Do NOT resend fields that weren't in the change set — it blows away history.
229
+ 2. Add new relationships via `lisa:atlassian-access` `operation: link from: <K1> to: <K2> type: "<link-type>"`. Existing links are not touched unless explicitly removed.
228
230
  3. If description changes, preserve sections you are not editing. Re-read via `/jira-read-ticket` first.
229
231
 
230
232
  ## Phase 7 — Verify
@@ -233,7 +235,7 @@ Call the `lisa:jira-verify` skill on the resulting ticket. `lisa:jira-verify` fe
233
235
 
234
236
  ## Phase 8 — Announce
235
237
 
236
- Post a creation comment via `mcp__atlassian__addCommentToJiraIssue` with:
238
+ Post a creation comment via `lisa:atlassian-access` `operation: comment key: <K> body: "..."` with:
237
239
  - `[{repo}]` prefix if the ticket is repo-scoped
238
240
  - Who the ticket is assigned to (if known)
239
241
  - The relationships that were set (`blocks`, `is blocked by`, `relates to`) with links
@@ -249,5 +251,5 @@ Skip this step only on UPDATE when no material change was made.
249
251
  - 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.
250
252
  - Never invent custom field values. If the project requires a field you don't have, stop and ask.
251
253
  - Never overwrite a description without reading the current version first.
252
- - All writes go through this skill so best practices are enforced uniformly. Downstream skills (e.g. `lisa:jira-create`) should delegate here rather than calling the MCP write tools directly.
254
+ - All writes go through this skill so best practices are enforced uniformly. Downstream skills (e.g. `lisa:jira-create`) should delegate here rather than invoking `lisa:atlassian-access` write operations directly.
253
255
  - The gate logic (what makes a valid ticket) lives in `lisa:jira-validate-ticket`, NOT in this skill. This skill calls the validator at Phase 5.5 (pre-write) and Phase 7 (via `lisa:jira-verify` post-write). When a gate needs to change, change it in `lisa:jira-validate-ticket` — every caller (write path, dry-run path, post-write verify) picks it up automatically.
@@ -83,6 +83,7 @@ Linear descriptions are markdown. Use `##` and `###` headings — not Jira wiki
83
83
  4. **Evidence names in kebab-case** — `api-response`, `schema-check`, `rate-limit-hit`.
84
84
  5. **Assertions are measurable** — "Returns 200 with `{status: ok}`" not "API works correctly".
85
85
  6. **Cover happy path and error path** — At minimum, one success and one failure evidence marker.
86
+ 7. **On a leaf work unit, the markers are binding** — For a Bug / Task / Sub-task / Improvement, every `[EVIDENCE: name]` here is the item's evidence manifest: validation gate S14 requires at least one, and the item cannot be closed until each named artifact is captured and attached (see the "Per-Work-Unit Evidence Contract" in the `verification` rule). Name only evidence you intend to capture — and name all of it.
86
87
 
87
88
  ### Step 6: Present to User for Approval
88
89
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: linear-build-intake
3
- description: "Symmetric counterpart to lisa:jira-build-intake on the Linear side. Scans a Linear team for Issues labeled status:ready, claims each by relabeling to status:in-progress, runs the implementation/build flow via lisa:linear-agent, and relabels to status:on-dev on completion. status:ready is the human-flipped signal that an Issue is truly ready for development — mirroring how Notion PRDs work Draft → Ready → (us) In Review → Blocked|Ticketed."
3
+ description: "Symmetric counterpart to lisa:jira-build-intake on the Linear side. Scans a Linear team for Issues carrying the configured `ready` build label, claims each by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:linear-agent, and relabels to the configured `done` label on completion. The `ready` label is the human-flipped signal that an Issue is truly ready for development — mirroring how Notion PRDs work Draft → Ready → (us) In Review → Blocked|Ticketed."
4
4
  allowed-tools: ["Skill", "Bash", "mcp__linear-server__list_teams", "mcp__linear-server__list_issues", "mcp__linear-server__get_issue", "mcp__linear-server__save_issue", "mcp__linear-server__save_comment", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label"]
5
5
  ---
6
6
 
@@ -8,25 +8,78 @@ allowed-tools: ["Skill", "Bash", "mcp__linear-server__list_teams", "mcp__linear-
8
8
 
9
9
  `$ARGUMENTS` is one of:
10
10
 
11
- 1. A Linear team key (e.g. `ENG`) — scans that team for `status:ready` Issues.
11
+ 1. A Linear team key (e.g. `ENG`) — scans that team for ready Issues.
12
12
  2. The literal token `linear` — falls back to `linear.teamKey` from `.lisa.config.json`.
13
13
  3. A pre-built Linear MCP filter (advanced) — used as-is.
14
14
 
15
- Run one build-intake cycle. Each `status:ready` Issue is claimed, built via the `lisa:linear-agent` flow, and relabeled to `status:on-dev` on completion. The cycle is the symmetric mirror of `lisa:jira-build-intake` and `lisa:github-build-intake`: humans flip `status:ready`, agents pick up and progress.
15
+ Run one build-intake cycle. Each ready Issue is claimed, built via the `lisa:linear-agent` flow, and relabeled to the configured `done` label on completion. The cycle is the symmetric mirror of `lisa:jira-build-intake` and `lisa:github-build-intake`: humans flip the `ready` label, agents pick up and progress.
16
16
 
17
17
  This skill is the destination of the `lisa:tracker-build-intake` shim when `tracker = "linear"`.
18
18
 
19
+ ## Workflow resolution
20
+
21
+ Build-queue label names are read from `.lisa.config.json` `linear.labels.build.*`, falling back to defaults documented in the `config-resolution` rule. Bash pattern:
22
+
23
+ ```bash
24
+ # Read role with default fallback. Local overrides global per-key.
25
+ read_role() {
26
+ local role="$1" default="$2"
27
+ local local_v global_v
28
+ local_v=$(jq -r ".linear.labels.build.${role} // empty" .lisa.config.local.json 2>/dev/null)
29
+ global_v=$(jq -r ".linear.labels.build.${role} // empty" .lisa.config.json 2>/dev/null)
30
+ echo "${local_v:-${global_v:-$default}}"
31
+ }
32
+
33
+ READY=$(read_role ready "status:ready")
34
+ CLAIMED=$(read_role claimed "status:in-progress")
35
+ REVIEW=$(read_role review "status:code-review")
36
+ ```
37
+
38
+ For env-keyed `done`, resolve the env first, then look up `done[<env>]`:
39
+
40
+ 1. Explicit caller arg (`target_env=staging`) wins.
41
+ 2. Otherwise, infer the env from the PR's base branch via `deploy.branches` (reverse lookup).
42
+ 3. If `done` is a **string** in config, use it directly regardless of env.
43
+ 4. If `done` is a **map** and env cannot be resolved, **fail loudly** — do not pick arbitrarily.
44
+
45
+ ```bash
46
+ TARGET_ENV="${target_env:-}"
47
+ if [ -z "$TARGET_ENV" ] && [ -n "$PR_BASE_BRANCH" ]; then
48
+ TARGET_ENV=$(jq -r --arg b "$PR_BASE_BRANCH" \
49
+ '.deploy.branches // {} | to_entries[] | select(.value == $b) | .key' \
50
+ .lisa.config.json 2>/dev/null | head -1)
51
+ fi
52
+
53
+ DONE_TYPE=$(jq -r '.linear.labels.build.done | type' .lisa.config.json 2>/dev/null)
54
+ if [ "$DONE_TYPE" = "string" ]; then
55
+ DONE=$(jq -r '.linear.labels.build.done' .lisa.config.json)
56
+ elif [ "$DONE_TYPE" = "object" ]; then
57
+ [ -z "$TARGET_ENV" ] && { echo "ERROR: linear.labels.build.done is env-keyed but env not resolvable"; exit 1; }
58
+ DONE=$(jq -r --arg e "$TARGET_ENV" '.linear.labels.build.done[$e] // empty' .lisa.config.json)
59
+ [ -z "$DONE" ] && { echo "ERROR: linear.labels.build.done has no entry for env '$TARGET_ENV'"; exit 1; }
60
+ else
61
+ case "$TARGET_ENV" in
62
+ dev) DONE="status:on-dev" ;;
63
+ staging) DONE="status:on-stg" ;;
64
+ production) DONE="status:done" ;;
65
+ *) echo "ERROR: cannot resolve done label without env"; exit 1 ;;
66
+ esac
67
+ fi
68
+ ```
69
+
70
+ In prose below, the role names refer to the resolved labels: e.g. "the `ready` label" means whatever `linear.labels.build.ready` resolves to (default: `status:ready`).
71
+
19
72
  ## Why labels, not native states
20
73
 
21
74
  Linear's per-team workflow state names vary (`Todo` / `Backlog` / `Up Next` / etc.). Labels are workspace-scoped or team-scoped and stable across teams, so we drive the build queue off labels rather than chasing renamed native states. The native `state` field is informational only for this skill.
22
75
 
23
76
  ## Configuration
24
77
 
25
- Reads `linear.workspace`, `linear.teamKey` from `.lisa.config.json` (with `.local` override).
78
+ Reads `linear.workspace`, `linear.teamKey`, and `linear.labels.build.*` from `.lisa.config.json` (with `.local` override).
26
79
 
27
80
  ## Confirmation policy
28
81
 
29
- Do NOT ask the caller whether to proceed. Once invoked with a team key, run the cycle to completion — claim, dispatch each Issue through `lisa:linear-agent`, transition successful builds to `status:on-dev`, write the summary. The caller (a human or a cron) has already authorized the run by invoking the skill.
82
+ Do NOT ask the caller whether to proceed. Once invoked with a team key, run the cycle to completion — claim, dispatch each Issue through `lisa:linear-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.
30
83
 
31
84
  Specifically forbidden:
32
85
 
@@ -38,21 +91,23 @@ Specifically forbidden:
38
91
  The only legitimate reasons to stop early:
39
92
 
40
93
  - Missing team key or required configuration. Surface and exit.
41
- - Label convention not yet adopted (`status:ready` does not exist on the team's labels). Surface and exit with an Adoption hint.
42
- - Empty `status:ready` set. Exit cleanly with `"No Linear Issues labeled status:ready. Nothing to do."`
94
+ - Label convention not yet adopted (the `ready` label does not exist on the team's labels). Surface and exit with an Adoption hint.
95
+ - Empty ready set. Exit cleanly with `"No Linear Issues labeled $READY. Nothing to do."`
43
96
 
44
97
  ## Lifecycle assumed
45
98
 
46
99
  Linear build queue uses these issue-level labels:
47
100
 
48
101
  ```text
49
- status:ready → status:in-progressstatus:code-review → status:on-dev → status:done
50
- (human/PM) (us claim) (us PR ready) (us build done) (downstream)
102
+ ready → claimed → review → done(env-keyed) (downstream)
103
+ (human/PM) (us claim) (us PR ready) (us build done)
51
104
  ```
52
105
 
53
- This skill ONLY transitions `status:ready → status:in-progress` on claim, and `status:in-progress → status:on-dev` on completion. It never touches `status:done`, `status:code-review` (owned by `lisa:linear-agent` / `lisa:linear-evidence`), or `status:blocked` (owned by `lisa:linear-agent`'s pre-flight gate).
106
+ (Defaults: `status:ready` / `status:in-progress` / `status:code-review` / `status:on-dev`/`status:on-stg`/`status:done`.)
107
+
108
+ This skill ONLY transitions `$READY → $CLAIMED` on claim, and `$CLAIMED → $DONE` on completion. It never touches `status:done`-as-terminal, `$REVIEW` (owned by `lisa:linear-agent` / `lisa:linear-evidence`), or `status:blocked` (owned by `lisa:linear-agent`'s pre-flight gate).
54
109
 
55
- **Pre-flight check**: at start of each cycle, confirm `status:ready`, `status:in-progress`, `status:on-dev` exist on the team via `mcp__linear-server__list_issue_labels`. If `status:ready` is missing, stop and report adoption needed. The other labels can be created on demand.
110
+ **Pre-flight check**: at start of each cycle, confirm `$READY`, `$CLAIMED`, and the relevant `$DONE` variants exist on the team via `mcp__linear-server__list_issue_labels`. If `$READY` is missing, stop and report adoption needed. The other labels can be created on demand.
56
111
 
57
112
  ## Phases
58
113
 
@@ -63,23 +118,23 @@ This skill ONLY transitions `status:ready → status:in-progress` on claim, and
63
118
  - Literal `linear` → fall back to `linear.teamKey` from config.
64
119
  2. Resolve team ID via `mcp__linear-server__list_teams({query: <teamKey>})`.
65
120
 
66
- ### Phase 2 — Find Ready Issues
121
+ ### Phase 2 — Find ready Issues
67
122
 
68
- Query: `mcp__linear-server__list_issues({team: <teamId>, label: "status:ready"})`.
123
+ Query: `mcp__linear-server__list_issues({team: <teamId>, label: "$READY"})`.
69
124
 
70
125
  Capture each Issue's: identifier, title, type label, priority, assignee, project, labels, description summary.
71
126
 
72
- If empty, report `"No Linear Issues labeled status:ready. Nothing to do."` and exit. Common idle case.
127
+ If empty, report `"No Linear Issues labeled $READY. Nothing to do."` and exit. Common idle case.
73
128
 
74
- ### Phase 3 — Process each Ready Issue (serial)
129
+ ### Phase 3 — Process each ready Issue (serial)
75
130
 
76
131
  #### 3a. Claim
77
132
 
78
- Update labels via `mcp__linear-server__save_issue`: remove `status:ready`, add `status:in-progress`. Resolve label IDs via `list_issue_labels` (create `status:in-progress` if missing).
133
+ Update labels via `mcp__linear-server__save_issue`: remove `$READY`, add `$CLAIMED`. Resolve label IDs via `list_issue_labels` (create `$CLAIMED` if missing).
79
134
 
80
135
  Post a `[claude-build-intake]` comment via `save_comment`: `"Claimed by Claude. Starting build."`
81
136
 
82
- This is the idempotency lock — a re-entrant cycle's `label: status:ready` filter will not see this Issue again.
137
+ This is the idempotency lock — a re-entrant cycle's `label: $READY` filter will not see this Issue again.
83
138
 
84
139
  If the relabel fails (permission, race), record under "Errors" and skip. **Do not invoke the build flow on an Issue you didn't successfully claim.**
85
140
 
@@ -96,20 +151,21 @@ Invoke `lisa:linear-agent` (per-Issue lifecycle agent) with the Issue identifier
96
151
  Wait for the agent to return. Capture its outcome:
97
152
  - **Success** — PR is ready (open or merged); evidence posted; ready for next status.
98
153
  - **Blocked by linear-verify pre-flight gate** — `lisa:linear-agent` itself relabels to `status:blocked` and assigns to creator. Let it stand. Record and move on.
99
- - **Blocked by ticket-triage ambiguities** — agent posts findings and stops. The Issue stays at `status:in-progress`. Surface to human; do not auto-transition. Record under "Errors".
100
- - **Errored** — exception, missing config, etc. Leave at `status:in-progress`. Record with exception summary.
154
+ - **Blocked by ticket-triage ambiguities** — agent posts findings and stops. The Issue stays at `$CLAIMED`. Surface to human; do not auto-transition. Record under "Errors".
155
+ - **Errored** — exception, missing config, etc. Leave at `$CLAIMED`. Record with exception summary.
101
156
 
102
- #### 3c. Relabel to status:on-dev (only on Success)
157
+ #### 3c. Relabel to $DONE (only on Success)
103
158
 
104
159
  If `lisa:linear-agent` returned Success:
105
- 1. Update labels via `mcp__linear-server__save_issue`: remove `status:in-progress`, add `status:on-dev`. (Note: at this point `lisa:linear-evidence` has typically already moved the Issue to `status:code-review` after PR creation. The transition is `status:code-review status:on-dev` if that's the current state.)
106
- 2. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL>. Transitioned to status:on-dev."`
160
+ 1. Resolve `$DONE` for this issue'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.
161
+ 2. Update labels via `mcp__linear-server__save_issue`: remove `$CLAIMED` (or `$REVIEW` if `lisa:linear-evidence` already moved it forward), add `$DONE`.
162
+ 3. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL>. Transitioned to $DONE."`
107
163
 
108
164
  For any non-Success outcome, do NOT transition. The Issue sits where the agent left it — humans take it from there.
109
165
 
110
166
  #### 3d. Continue
111
167
 
112
- Move to the next Ready Issue. One Issue failing does not stop others.
168
+ Move to the next ready Issue. One Issue failing does not stop others.
113
169
 
114
170
  ### Phase 4 — Summary report
115
171
 
@@ -121,7 +177,7 @@ Cycle started: <ISO timestamp>
121
177
  Cycle completed: <ISO timestamp>
122
178
 
123
179
  Issues processed: <n>
124
- - status:on-dev (build complete, PR ready): <n>
180
+ - $DONE (build complete, PR ready): <n>
125
181
  - <ID> <title> → PR <URL>
126
182
  - status:blocked (pre-flight verify failed): <n>
127
183
  - <ID> <title> — see Issue comments
@@ -135,26 +191,28 @@ Total PRs opened: <n>
135
191
 
136
192
  ## Idempotency & safety
137
193
 
138
- - **Claim-first ordering**: `status:in-progress` set BEFORE agent invocation — no double-pickup.
139
- - **No writes outside the lifecycle**: this skill only adds/removes `status:ready`, `status:in-progress`, `status:on-dev`. Every other label change (and the native state) is owned by the agent or `lisa:linear-evidence`.
194
+ - **Claim-first ordering**: `$CLAIMED` set BEFORE agent invocation — no double-pickup.
195
+ - **No writes outside the lifecycle**: this skill only adds/removes `$READY`, `$CLAIMED`, `$DONE`. Every other label change (and the native state) is owned by the agent or `lisa:linear-evidence`.
140
196
  - **Failure isolation**: per-Issue exceptions caught and recorded; the cycle continues.
141
197
  - **Single cycle per team**: do not run two concurrent cycles against the same team — concurrent claims could race.
142
198
  - **Single-label invariant**: after every transition, verify exactly one `status:*` label is present. Two simultaneously breaks the build queue.
199
+ - **Never pick an arbitrary env for `$DONE`**. If `done` is a map and env is ambiguous, fail loudly.
143
200
 
144
201
  ## Adoption (one-time per team)
145
202
 
146
- Before this skill can run against a Linear team, the team must adopt the `status:*` issue-label convention:
203
+ Before this skill can run against a Linear team, the team must adopt the build-queue label convention. Using the defaults:
147
204
 
148
- 1. Create labels `status:ready`, `status:in-progress`, `status:code-review`, `status:on-dev`, `status:done`, `status:blocked` on the team (or workspace).
149
- 2. Apply `status:ready` to Issues that are ready for development.
150
- 3. Reserve `status:in-progress`, `status:code-review`, `status:on-dev` for Lisa — humans should not set them manually except to recover from an error.
205
+ 1. Create labels `status:ready`, `status:in-progress`, `status:code-review`, `status:on-dev`, `status:done`, `status:blocked` on the team (or workspace). If your project overrides any `linear.labels.build.*` role name in config, substitute the actual label names you configured.
206
+ 2. Apply the `$READY` label to Issues that are ready for development.
207
+ 3. Reserve `$CLAIMED`, `$REVIEW`, `$DONE` for Lisa — humans should not set them manually except to recover from an error.
151
208
 
152
209
  If the team hasn't adopted these labels, the first run exits with an adoption hint.
153
210
 
154
211
  ## Rules
155
212
 
156
- - Never relabel an Issue the cycle didn't claim. The `status:in-progress` transition is the signature of cycle ownership.
213
+ - Never relabel an Issue the cycle didn't claim. The `$CLAIMED` transition is the signature of cycle ownership.
157
214
  - Never bypass `lisa:linear-agent` to do build work directly. The agent owns the per-Issue lifecycle.
158
- - Never auto-transition past `status:on-dev`. Downstream labels (`status:done`) are owned by QA / product / a future verification-intake skill.
215
+ - Never auto-transition past `$DONE`. Downstream labels are owned by QA / product / a future verification-intake skill.
159
216
  - If the Issue has no Validation Journey or no sign-in credentials in its description, `lisa:linear-agent`'s pre-flight verify will catch it and relabel to `status:blocked` — don't try to fix the Issue from here.
160
217
  - On any unexpected response from `lisa:linear-agent` (label it doesn't claim, missing PR URL on success, etc.), record as Error and surface — never assume.
218
+ - Never pick an arbitrary env for `$DONE` resolution. If `done` is a map and env is ambiguous, fail loudly.
@@ -1,18 +1,35 @@
1
1
  ---
2
2
  name: linear-evidence
3
- description: "Uploads text evidence to the GitHub `pr-assets` release, updates the PR description, posts a comment on the originating Linear Issue with code blocks, and transitions the Issue from in-progress to code-review by relabeling. Reusable by any skill that captures evidence and generates evidence/comment.txt + evidence/code-blocks.md. Linear counterpart of lisa:jira-evidence and lisa:github-evidence."
3
+ description: "Uploads text evidence to the GitHub `pr-assets` release, updates the PR description, posts a comment on the originating Linear Issue with code blocks, and transitions the Issue from the configured `claimed` label to the configured `review` label. Reusable by any skill that captures evidence and generates evidence/comment.txt + evidence/code-blocks.md. Linear counterpart of lisa:jira-evidence and lisa:github-evidence."
4
4
  allowed-tools: ["Bash", "Skill", "mcp__linear-server__list_teams", "mcp__linear-server__get_issue", "mcp__linear-server__save_issue", "mcp__linear-server__save_comment", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label"]
5
5
  ---
6
6
 
7
7
  # Linear Evidence: $ARGUMENTS
8
8
 
9
- Post verification evidence to a Linear Issue and transition it to the code-review state. This skill is the destination of the `lisa:tracker-evidence` shim when `tracker = "linear"`.
9
+ Post verification evidence to a Linear Issue and transition it from the configured `claimed` build label to the configured `review` build label. This skill is the destination of the `lisa:tracker-evidence` shim when `tracker = "linear"`.
10
10
 
11
11
  `$ARGUMENTS` is the Linear Issue identifier (e.g. `ENG-123`) and the path to the evidence directory. Caller passes both: `<IDENTIFIER> <evidence-dir>`.
12
12
 
13
+ ## Workflow resolution
14
+
15
+ The `claimed` and `review` build labels are read from `.lisa.config.json` `linear.labels.build.*`, falling back to the defaults documented in the `config-resolution` rule (`status:in-progress` and `status:code-review`).
16
+
17
+ ```bash
18
+ read_role() {
19
+ local role="$1" default="$2"
20
+ local local_v global_v
21
+ local_v=$(jq -r ".linear.labels.build.${role} // empty" .lisa.config.local.json 2>/dev/null)
22
+ global_v=$(jq -r ".linear.labels.build.${role} // empty" .lisa.config.json 2>/dev/null)
23
+ echo "${local_v:-${global_v:-$default}}"
24
+ }
25
+
26
+ CLAIMED=$(read_role claimed "status:in-progress")
27
+ REVIEW=$(read_role review "status:code-review")
28
+ ```
29
+
13
30
  ## Configuration
14
31
 
15
- Reads `linear.workspace`, `linear.teamKey` from `.lisa.config.json` (with `.local` override).
32
+ Reads `linear.workspace`, `linear.teamKey`, and `linear.labels.build.*` from `.lisa.config.json` (with `.local` override).
16
33
 
17
34
  ## Inputs (in `<evidence-dir>`)
18
35
 
@@ -66,7 +83,7 @@ Linear comments support markdown including `<details>` collapsibles, fenced code
66
83
 
67
84
  ## Phase 5 — Transition Status
68
85
 
69
- Update labels via `mcp__linear-server__save_issue` to remove `status:in-progress` and add `status:code-review`. Resolve label IDs first via `mcp__linear-server__list_issue_labels` (create the label via `create_issue_label` if it doesn't exist on the team).
86
+ Update labels via `mcp__linear-server__save_issue` to remove `$CLAIMED` and add `$REVIEW`. Resolve label IDs first via `mcp__linear-server__list_issue_labels` (create the label via `create_issue_label` if it doesn't exist on the team).
70
87
 
71
88
  The native Linear `state` field is also updated to the team's "In Review" state if one exists — but the label remains the source of truth for cross-team consistency.
72
89
 
@@ -81,6 +98,6 @@ Return:
81
98
  ## Rules
82
99
 
83
100
  - Never modify the Issue description as part of evidence posting — comments only. Description edits go through `lisa:linear-write-issue`.
84
- - Never skip the label transition. The build queue is keyed off `status:*` labels; an item that ships without transitioning is invisible to monitoring.
101
+ - Never skip the label transition. The build queue is keyed off the configured `linear.labels.build.*` labels; an item that ships without transitioning is invisible to monitoring.
85
102
  - If `mcp__linear-server__save_comment` fails, retry once. If it fails again, surface the error — don't pretend the comment was posted.
86
103
  - Do not delete prior comments. The history is the audit trail.