@codyswann/lisa 2.326.3 → 2.328.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 (245) hide show
  1. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  2. package/dist/core/upstream-evidence-manifest.js +55 -29
  3. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  4. package/dist/sync/lifecycle-defaults.d.ts +61 -0
  5. package/dist/sync/lifecycle-defaults.d.ts.map +1 -0
  6. package/dist/sync/lifecycle-defaults.js +75 -0
  7. package/dist/sync/lifecycle-defaults.js.map +1 -0
  8. package/dist/sync/registry.d.ts.map +1 -1
  9. package/dist/sync/registry.js +15 -23
  10. package/dist/sync/registry.js.map +1 -1
  11. package/package.json +1 -1
  12. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa/.codex-plugin/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
  15. package/plugins/lisa/.codex-plugin/skills/lisa-detect-tooling/SKILL.md +21 -1
  16. package/plugins/lisa/.codex-plugin/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +25 -13
  17. package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +1 -1
  18. package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +1 -1
  19. package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
  20. package/plugins/lisa/.codex-plugin/skills/lisa-linear-access/SKILL.md +20 -9
  21. package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +76 -66
  22. package/plugins/lisa/.codex-plugin/skills/lisa-linear-claim/SKILL.md +1 -1
  23. package/plugins/lisa/.codex-plugin/skills/lisa-linear-evidence/SKILL.md +7 -7
  24. package/plugins/lisa/.codex-plugin/skills/lisa-linear-journey/SKILL.md +2 -2
  25. package/plugins/lisa/.codex-plugin/skills/lisa-linear-sync/SKILL.md +34 -30
  26. package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  27. package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +6 -6
  28. package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +8 -7
  29. package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  30. package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +1 -1
  31. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/validate-config.mjs +72 -10
  32. package/plugins/lisa/.codex-plugin/skills/lisa-setup-linear/SKILL.md +59 -12
  33. package/plugins/lisa/.codex-plugin/skills/lisa-setup-local-env/SKILL.md +95 -0
  34. package/plugins/lisa/.codex-plugin/skills/lisa-setup-local-env/agents/openai.yaml +4 -0
  35. package/plugins/lisa/.codex-plugin/skills/lisa-setup-local-env/scripts/local-env.mjs +174 -0
  36. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/SKILL.md +27 -11
  37. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +70 -30
  38. package/plugins/lisa/.codex-plugin/skills/lisa-setup-remote-env/scripts/toolchain.mjs +132 -6
  39. package/plugins/lisa/.codex-plugin/skills/lisa-tracker-sync/SKILL.md +2 -2
  40. package/plugins/lisa/agents/linear-agent.md +6 -6
  41. package/plugins/lisa/agents/linear-build-intake.md +3 -3
  42. package/plugins/lisa/commands/setup/local-env.md +7 -0
  43. package/plugins/lisa/rules/eager/rejection-detection.md +2 -2
  44. package/plugins/lisa/rules/reference/config-resolution.md +37 -9
  45. package/plugins/lisa/rules/reference/rejection-detection.md +2 -2
  46. package/plugins/lisa/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
  47. package/plugins/lisa/skills/lisa-detect-tooling/SKILL.md +21 -1
  48. package/plugins/lisa/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +25 -13
  49. package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +1 -1
  50. package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +1 -1
  51. package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
  52. package/plugins/lisa/skills/lisa-linear-access/SKILL.md +20 -9
  53. package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +77 -67
  54. package/plugins/lisa/skills/lisa-linear-claim/SKILL.md +1 -1
  55. package/plugins/lisa/skills/lisa-linear-evidence/SKILL.md +7 -7
  56. package/plugins/lisa/skills/lisa-linear-journey/SKILL.md +2 -2
  57. package/plugins/lisa/skills/lisa-linear-sync/SKILL.md +34 -30
  58. package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  59. package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +6 -6
  60. package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +8 -7
  61. package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  62. package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +1 -1
  63. package/plugins/lisa/skills/lisa-secrets-access/scripts/validate-config.mjs +72 -10
  64. package/plugins/lisa/skills/lisa-setup-linear/SKILL.md +59 -12
  65. package/plugins/lisa/skills/lisa-setup-local-env/SKILL.md +95 -0
  66. package/plugins/lisa/skills/lisa-setup-local-env/agents/openai.yaml +4 -0
  67. package/plugins/lisa/skills/lisa-setup-local-env/scripts/local-env.mjs +174 -0
  68. package/plugins/lisa/skills/lisa-setup-remote-env/SKILL.md +27 -11
  69. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +70 -30
  70. package/plugins/lisa/skills/lisa-setup-remote-env/scripts/toolchain.mjs +132 -6
  71. package/plugins/lisa/skills/lisa-tracker-build-intake/SKILL.md +1 -1
  72. package/plugins/lisa/skills/lisa-tracker-sync/SKILL.md +2 -2
  73. package/plugins/lisa-agy/agents/linear-agent.md +6 -6
  74. package/plugins/lisa-agy/agents/linear-build-intake.md +3 -3
  75. package/plugins/lisa-agy/commands/lisa/setup/local-env.md +7 -0
  76. package/plugins/lisa-agy/plugin.json +1 -1
  77. package/plugins/lisa-agy/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
  78. package/plugins/lisa-agy/skills/lisa-detect-tooling/SKILL.md +21 -1
  79. package/plugins/lisa-agy/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +25 -13
  80. package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +1 -1
  81. package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +1 -1
  82. package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
  83. package/plugins/lisa-agy/skills/lisa-linear-access/SKILL.md +20 -9
  84. package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +77 -67
  85. package/plugins/lisa-agy/skills/lisa-linear-claim/SKILL.md +1 -1
  86. package/plugins/lisa-agy/skills/lisa-linear-evidence/SKILL.md +7 -7
  87. package/plugins/lisa-agy/skills/lisa-linear-journey/SKILL.md +2 -2
  88. package/plugins/lisa-agy/skills/lisa-linear-sync/SKILL.md +34 -30
  89. package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  90. package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +6 -6
  91. package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +8 -7
  92. package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  93. package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +1 -1
  94. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/validate-config.mjs +72 -10
  95. package/plugins/lisa-agy/skills/lisa-setup-linear/SKILL.md +59 -12
  96. package/plugins/lisa-agy/skills/lisa-setup-local-env/SKILL.md +95 -0
  97. package/plugins/lisa-agy/skills/lisa-setup-local-env/scripts/local-env.mjs +174 -0
  98. package/plugins/lisa-agy/skills/lisa-setup-remote-env/SKILL.md +27 -11
  99. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +70 -30
  100. package/plugins/lisa-agy/skills/lisa-setup-remote-env/scripts/toolchain.mjs +132 -6
  101. package/plugins/lisa-agy/skills/lisa-tracker-build-intake/SKILL.md +1 -1
  102. package/plugins/lisa-agy/skills/lisa-tracker-sync/SKILL.md +2 -2
  103. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  106. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-copilot/agents/linear-agent.agent.md +6 -6
  110. package/plugins/lisa-copilot/agents/linear-build-intake.agent.md +3 -3
  111. package/plugins/lisa-copilot/commands/lisa/setup/local-env.md +7 -0
  112. package/plugins/lisa-copilot/rules/eager/rejection-detection.md +2 -2
  113. package/plugins/lisa-copilot/rules/reference/config-resolution.md +37 -9
  114. package/plugins/lisa-copilot/rules/reference/rejection-detection.md +2 -2
  115. package/plugins/lisa-copilot/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
  116. package/plugins/lisa-copilot/skills/lisa-detect-tooling/SKILL.md +21 -1
  117. package/plugins/lisa-copilot/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +25 -13
  118. package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +1 -1
  119. package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +1 -1
  120. package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
  121. package/plugins/lisa-copilot/skills/lisa-linear-access/SKILL.md +20 -9
  122. package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +77 -67
  123. package/plugins/lisa-copilot/skills/lisa-linear-claim/SKILL.md +1 -1
  124. package/plugins/lisa-copilot/skills/lisa-linear-evidence/SKILL.md +7 -7
  125. package/plugins/lisa-copilot/skills/lisa-linear-journey/SKILL.md +2 -2
  126. package/plugins/lisa-copilot/skills/lisa-linear-sync/SKILL.md +34 -30
  127. package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  128. package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +6 -6
  129. package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +8 -7
  130. package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  131. package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +1 -1
  132. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/validate-config.mjs +72 -10
  133. package/plugins/lisa-copilot/skills/lisa-setup-linear/SKILL.md +59 -12
  134. package/plugins/lisa-copilot/skills/lisa-setup-local-env/SKILL.md +95 -0
  135. package/plugins/lisa-copilot/skills/lisa-setup-local-env/scripts/local-env.mjs +174 -0
  136. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/SKILL.md +27 -11
  137. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +70 -30
  138. package/plugins/lisa-copilot/skills/lisa-setup-remote-env/scripts/toolchain.mjs +132 -6
  139. package/plugins/lisa-copilot/skills/lisa-tracker-build-intake/SKILL.md +1 -1
  140. package/plugins/lisa-copilot/skills/lisa-tracker-sync/SKILL.md +2 -2
  141. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  142. package/plugins/lisa-cursor/agents/linear-agent.md +6 -6
  143. package/plugins/lisa-cursor/agents/linear-build-intake.md +3 -3
  144. package/plugins/lisa-cursor/commands/lisa/setup/local-env.md +7 -0
  145. package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +37 -9
  146. package/plugins/lisa-cursor/rules/rejection-detection-reference.mdc +2 -2
  147. package/plugins/lisa-cursor/rules/rejection-detection.mdc +2 -2
  148. package/plugins/lisa-cursor/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
  149. package/plugins/lisa-cursor/skills/lisa-detect-tooling/SKILL.md +21 -1
  150. package/plugins/lisa-cursor/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +25 -13
  151. package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +1 -1
  152. package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +1 -1
  153. package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
  154. package/plugins/lisa-cursor/skills/lisa-linear-access/SKILL.md +20 -9
  155. package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +77 -67
  156. package/plugins/lisa-cursor/skills/lisa-linear-claim/SKILL.md +1 -1
  157. package/plugins/lisa-cursor/skills/lisa-linear-evidence/SKILL.md +7 -7
  158. package/plugins/lisa-cursor/skills/lisa-linear-journey/SKILL.md +2 -2
  159. package/plugins/lisa-cursor/skills/lisa-linear-sync/SKILL.md +34 -30
  160. package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  161. package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +6 -6
  162. package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +8 -7
  163. package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  164. package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +1 -1
  165. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/validate-config.mjs +72 -10
  166. package/plugins/lisa-cursor/skills/lisa-setup-linear/SKILL.md +59 -12
  167. package/plugins/lisa-cursor/skills/lisa-setup-local-env/SKILL.md +95 -0
  168. package/plugins/lisa-cursor/skills/lisa-setup-local-env/scripts/local-env.mjs +174 -0
  169. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/SKILL.md +27 -11
  170. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +70 -30
  171. package/plugins/lisa-cursor/skills/lisa-setup-remote-env/scripts/toolchain.mjs +132 -6
  172. package/plugins/lisa-cursor/skills/lisa-tracker-build-intake/SKILL.md +1 -1
  173. package/plugins/lisa-cursor/skills/lisa-tracker-sync/SKILL.md +2 -2
  174. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  175. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  176. package/plugins/lisa-expo-agy/plugin.json +1 -1
  177. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  178. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  179. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  180. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  181. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  182. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  183. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  184. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  185. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  186. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  187. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  188. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  189. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  190. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  191. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  192. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  193. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  194. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  195. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  196. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  197. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  198. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  199. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  200. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  201. package/plugins/lisa-rails-agy/plugin.json +1 -1
  202. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  203. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  204. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  205. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  206. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  207. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  208. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  209. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  210. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  211. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  212. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  213. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  214. package/plugins/src/base/agents/linear-agent.md +6 -6
  215. package/plugins/src/base/agents/linear-build-intake.md +3 -3
  216. package/plugins/src/base/commands/setup/local-env.md +7 -0
  217. package/plugins/src/base/rules/eager/rejection-detection.md +2 -2
  218. package/plugins/src/base/rules/reference/config-resolution.md +37 -9
  219. package/plugins/src/base/rules/reference/rejection-detection.md +2 -2
  220. package/plugins/src/base/skills/lisa-confluence-to-tracker/SKILL.md +3 -3
  221. package/plugins/src/base/skills/lisa-detect-tooling/SKILL.md +21 -1
  222. package/plugins/src/base/skills/lisa-detect-tooling/scripts/detect-tooling.mjs +25 -13
  223. package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +1 -1
  224. package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +1 -1
  225. package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +1 -1
  226. package/plugins/src/base/skills/lisa-linear-access/SKILL.md +20 -9
  227. package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +77 -67
  228. package/plugins/src/base/skills/lisa-linear-claim/SKILL.md +1 -1
  229. package/plugins/src/base/skills/lisa-linear-evidence/SKILL.md +7 -7
  230. package/plugins/src/base/skills/lisa-linear-journey/SKILL.md +2 -2
  231. package/plugins/src/base/skills/lisa-linear-sync/SKILL.md +34 -30
  232. package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +3 -3
  233. package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +6 -6
  234. package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +8 -7
  235. package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +3 -3
  236. package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +1 -1
  237. package/plugins/src/base/skills/lisa-secrets-access/scripts/validate-config.mjs +72 -10
  238. package/plugins/src/base/skills/lisa-setup-linear/SKILL.md +59 -12
  239. package/plugins/src/base/skills/lisa-setup-local-env/SKILL.md +95 -0
  240. package/plugins/src/base/skills/lisa-setup-local-env/scripts/local-env.mjs +174 -0
  241. package/plugins/src/base/skills/lisa-setup-remote-env/SKILL.md +27 -11
  242. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/setup-remote-env.mjs +70 -30
  243. package/plugins/src/base/skills/lisa-setup-remote-env/scripts/toolchain.mjs +132 -6
  244. package/plugins/src/base/skills/lisa-tracker-build-intake/SKILL.md +1 -1
  245. package/plugins/src/base/skills/lisa-tracker-sync/SKILL.md +2 -2
@@ -17,7 +17,7 @@ skills:
17
17
 
18
18
  You are a Linear build-intake agent. Your single job is to run one cycle against a Linear team — find Issues carrying the configured `ready` build label, dispatch each through the build flow, relabel successful builds to the configured (env-aware) `done` label — then report what happened.
19
19
 
20
- Build-label role names (`ready`, `claimed`, `review`, `done`) are resolved from `.lisa.config.json` `linear.labels.build.*` by the `linear-build-intake` skill. The defaults match the legacy hardcoded names (`status:ready`, `status:in-progress`, `status:code-review`, env-keyed `{ dev: status:on-dev, staging: status:on-stg, production: status:done }`).
20
+ Build-lifecycle role names (`ready`, `claimed`, `review`, `blocked`, `done`) are resolved from `.lisa.config.json` `linear.workflow.*` by the `linear-build-intake` skill, and name native **workflow states**, not labels. Defaults: `Todo`, `In Progress`, `In Review`, `Blocked`, env-keyed `{ dev: "On Dev", staging: "On Stg", production: "Done" }`.
21
21
 
22
22
  ## Confirmation policy
23
23
 
@@ -27,7 +27,7 @@ Once you have a team key, RUN. Do not ask the caller whether to proceed, do not
27
27
 
28
28
  ### 1. Receive the query
29
29
 
30
- The invoking caller (a slash command, a scheduled cron, or a parent agent) hands you a Linear team key (e.g. `ENG`) or the literal token `linear` (which falls back to `linear.teamKey` in `.lisa.config.json`). You do not pick the team yourself. Lifecycle label names are read from `linear.labels.build.*` and are not your concern at this layer.
30
+ The invoking caller (a slash command, a scheduled cron, or a parent agent) hands you a Linear team key (e.g. `ENG`) or the literal token `linear` (which falls back to `linear.teamKey` in `.lisa.config.json`). You do not pick the team yourself. Lifecycle label names are read from `linear.workflow.*` and are not your concern at this layer.
31
31
 
32
32
  If no query is provided AND no `linear.teamKey` is configured, stop and ask. Never run intake against a default scope without explicit configuration — the side effects (label transitions, PRs opened, builds running) are too high to act without an explicit target.
33
33
 
@@ -58,7 +58,7 @@ If any Issues ended at the configured `blocked` label (pre-flight verify failed)
58
58
  - **Never run a cycle without an explicit query or configured `linear.teamKey`.** Side effects too high to default.
59
59
  - **Never modify the lifecycle**: only the configured `ready → claimed → done` transitions and terminal-only native Issue completion. Never touch the configured `blocked` label (owned by `linear-agent`) or any other label. (Exception: the configured `review` label is set by `linear-evidence` mid-flow — that's not your concern.)
60
60
  - **Never bypass `linear-agent` to do build work directly.** The intake skill dispatches; `linear-agent` builds. Skipping the dispatch produces broken work.
61
- - **Never invent labels.** Names live in `.lisa.config.json` `linear.labels.build.*` (canonical) — the setup skill writes them. If a team hasn't adopted them yet, the skill exits with an adoption hint. Don't guess label names.
61
+ - **Never invent labels.** Names live in `.lisa.config.json` `linear.workflow.*` (canonical) — the setup skill writes them. If a team hasn't adopted them yet, the skill exits with an adoption hint. Don't guess label names.
62
62
  - **Never start a second cycle while one is in flight against an overlapping team.** Serial execution. Scheduling layer (when added) is responsible for not double-firing.
63
63
  - **Stop and surface failures rather than retry-loop.** If `linear-agent` returns an unexpected response or an error, the skill records it under "Errors" — pass that through. Do not auto-retry.
64
64
  - **Pre-flight failures are not your problem to fix.** If an Issue fails `linear-verify` (missing Validation Journey, sign-in, etc.), `linear-agent` transitions it to the configured `blocked` label and reassigns to the creator. Surface the count and move on. Do NOT try to add the missing pieces from this agent.
@@ -0,0 +1,7 @@
1
+ ---
2
+ description: "Bring this machine in line with the toolchain the project declares. Reports every tool in remoteEnv.tools that is missing, outdated, or unpinned for this platform, and installs the missing ones into ~/.local/bin from the same pinned, checksummed entries the remote surfaces use — but only when asked with --install-tools. A newer tool already on PATH is left alone."
3
+ allowed-tools: ["Skill"]
4
+ argument-hint: "[--install-tools] [--json]"
5
+ ---
6
+
7
+ Use the /lisa-setup-local-env skill to report and optionally install the project's declared toolchain on this machine. $ARGUMENTS
@@ -21,9 +21,9 @@ Return exactly one of:
21
21
 
22
22
  - **GitHub** — `LABELED` / `UNLABELED` timeline events on the configured **ready** label (the Label-Event History surface from `lisa-github-read-issue`).
23
23
  - **JIRA** — the `changelog` operation on `lisa-atlassian-access` (`?expand=changelog`, status items).
24
- - **Linear** — the `history` operation on `lisa-linear-access`, keyed on `status:*` label history (`addedLabelIds`/`removedLabelIds` resolved against `list-issue-labels`).
24
+ - **Linear** — the `history` operation on `lisa-linear-access`, keyed on **workflow-state** history (`fromState.name` / `toState.name`, inlined on each node — no label-ID resolution needed).
25
25
 
26
- **Lane names ALWAYS come from `.lisa.config.json` lanes** (`github.labels.build.{ready,claimed,done}` and the JIRA/Linear equivalents; `src/sync/registry.ts` `BUILD_LABEL_DEFAULTS`). **Never hardcode** `status:ready`, `Ready`, etc.
26
+ **Lane names ALWAYS come from `.lisa.config.json` lanes** (`github.labels.build.{ready,claimed,done}` for GitHub, `jira.workflow.*` and `linear.workflow.*` for the status/state trackers; `src/sync/registry.ts` `BUILD_LABEL_DEFAULTS` and `LINEAR_WORKFLOW_DEFAULTS`). **Never hardcode** `status:ready`, `Ready`, `Todo`, etc.
27
27
 
28
28
  ## Never block the build
29
29
 
@@ -344,6 +344,28 @@ When `github.projects.v2` is present, later setup/doctor and writer preflight va
344
344
  |-------|---------------|-------|
345
345
  | `linear.workspace` | `tracker = "linear"`, `source = "linear"`, or any `linear-*` skill is invoked | Linear workspace slug (e.g. `acme`). |
346
346
  | `linear.teamKey` | `tracker = "linear"` | Linear team key (e.g. `ENG`). The team owns the destination Issues. For source mode, projects are workspace-scoped or team-scoped per the URL passed. |
347
+ | `linear.workflow` | `tracker = "linear"` | Workflow **state** name per build lifecycle role — the Linear analogue of `jira.workflow`, not of `github.labels`. Defaults `{ ready: "Todo", claimed: "In Progress", review: "In Review", blocked: "Blocked", done: { dev: "On Dev", staging: "On Stg", production: "Done" } }`. Resolve and verify with `/lisa:setup:linear`. |
348
+ | `linear.labels` | `tracker = "linear"` or `source = "linear"` | **Markers and the PRD lane only.** `build.human_needed` (default `human-needed`) and the `prd.*` map. The build lifecycle does **not** live here — see `linear.workflow`. |
349
+
350
+ ##### Why Linear uses states, not labels
351
+
352
+ Linear Issues carry first-class workflow states with a machine-readable `type`
353
+ (`backlog` / `unstarted` / `started` / `completed` / `canceled`) — the same shape
354
+ JIRA statuses have. GitHub Issues has no such field (only open/closed), which is
355
+ why the GitHub adapter *must* use labels; that is a constraint of GitHub's data
356
+ model, not a Lisa preference, and Linear does not share it.
357
+
358
+ Driving Linear off labels left **two writers on one lifecycle**: Linear's own git
359
+ automations move `state` on merge while Lisa moved only labels. The two then
360
+ disagreed permanently on any merge that did not run through a Lisa flow, and the
361
+ env rungs (`On Dev` / `On Stg`) could never appear on a Linear board, cycle or
362
+ insight at all, because those group by state.
363
+
364
+ The historical objection was that per-team state NAMES vary and get renamed. That
365
+ is equally true of JIRA statuses, which Lisa keys on regardless, and Linear
366
+ additionally exposes the rename-proof `type` discriminator that the lifecycle
367
+ skills already use for terminal detection. Names live in config, so a project
368
+ that renames a state overrides one key.
347
369
 
348
370
  #### `verification.browser.kane`
349
371
 
@@ -405,16 +427,20 @@ Every lifecycle skill operates on a fixed set of **roles** (`ready`, `claimed`,
405
427
 
406
428
  **Build lifecycle** (work items):
407
429
 
408
- | Role | What it means | JIRA default | GitHub/Linear default |
409
- |---|---|---|---|
410
- | `ready` | Human signal "this is buildable; agent may claim" | `Ready` (status) | `status:ready` (label) |
411
- | `claimed` | Agent has picked the item up | `In Progress` (status) | `status:in-progress` (label) |
412
- | `review` | Optional post-build review hold, when a tracker/project still uses one | `Code Review` (status) | Linear default: `status:code-review`; GitHub has no default review label |
413
- | `blocked` | Agent stopped on triage ambiguities or external blocker | `Blocked` (status) | `status:blocked` (label) |
414
- | `done` | Terminal state for this work, **env-keyed** | map of env → status | map of env → label |
430
+ | Role | What it means | JIRA default | Linear default | GitHub default |
431
+ |---|---|---|---|---|
432
+ | `ready` | Human signal "this is buildable; agent may claim" | `Ready` (status) | `Todo` (state) | `status:ready` (label) |
433
+ | `claimed` | Agent has picked the item up | `In Progress` (status) | `In Progress` (state) | `status:in-progress` (label) |
434
+ | `review` | Optional post-build review hold, when a tracker/project still uses one | `Code Review` (status) | `In Review` (state) | no default review label |
435
+ | `blocked` | Agent stopped on triage ambiguities or external blocker | `Blocked` (status) | `Blocked` (state) | `status:blocked` (label) |
436
+ | `done` | Terminal state for this work, **env-keyed** | map of env → status | map of env → state | map of env → label |
437
+
438
+ **JIRA and Linear resolve roles to native workflow statuses/states** (`jira.workflow`, `linear.workflow`); **GitHub resolves them to labels** (`github.labels.build`) because GitHub Issues has no workflow-state field at all. A role transition is therefore a *state move* on JIRA and Linear, and a *label swap* on GitHub. Skills operate on roles and never hardcode either form.
415
439
 
416
440
  `review` is optional. GitHub build intake skips it by default and moves successful builds directly from `claimed` to the configured `done` label. Linear and JIRA projects that still use a post-build review hold can configure `review`; projects that keep the ticket in `claimed` until terminal can omit it and lifecycle skills will skip the intermediate transition.
417
441
 
442
+ **Linear state resolution is `type`-aware.** When a configured name is missing, a lifecycle skill may fall back to the team's states by `type` — `ready` → the lowest-position `unstarted`, `claimed` → the lowest-position `started`, terminal `done` → `completed` — but only to *read*; it must never invent a state to write into. Missing states are a setup defect, repaired by `/lisa:setup:linear`, not papered over at runtime.
443
+
418
444
  `blocked` is what every vendor agent flips to when triage finds unresolved ambiguities or the build path is blocked by something the agent can't resolve. Different from `claimed` because it explicitly signals "human attention required."
419
445
 
420
446
  #### Build markers (additive labels, not lifecycle roles)
@@ -425,11 +451,13 @@ A **marker** is an additive label applied *alongside* a lifecycle role, not a st
425
451
  |---|---|---|---|
426
452
  | `human_needed` | Applied with `blocked` when — **after the agent has drafted every authorable missing section via the `pre-flight-autofill` procedure** — the block still requires a human to confirm the drafted assumptions or supply something no agent can invent: real missing credentials, access/permissions, or an irreducible product/scoping decision. | `Human Needed` (label) | `human-needed` (label) |
427
453
 
454
+ Markers are labels on **every** vendor, Linear included — that is the one place the Linear build lane still touches `linear.labels`.
455
+
428
456
  Resolution keys:
429
457
 
430
458
  - JIRA: `jira.labels.human_needed` (default `Human Needed`). Applied as a JIRA **label** — not a workflow status — because an item holds exactly one status but any number of labels. The `blocked` status still drives the lifecycle; `human_needed` is the additive marker on top of it.
431
459
  - GitHub: `github.labels.build.human_needed` (default `human-needed`). Added next to the `blocked` label.
432
- - Linear: `linear.labels.build.human_needed` (default `human-needed`). Added next to the `blocked` label.
460
+ - Linear: `linear.labels.build.human_needed` (default `human-needed`). Applied as a Linear **label**, for the same reason as JIRA — an Issue holds exactly one workflow state but any number of labels, so an additive marker cannot be a state. The `blocked` **state** still drives the lifecycle; `human_needed` is the marker on top of it. This is the only build-lane key left in `linear.labels`.
433
461
 
434
462
  **When to apply it.** Apply `human_needed` only when a human must act before the item can move — the pre-flight gate failures that bounce a ticket back to its reporter are exactly this case, but **only after** the agent has run the `pre-flight-autofill` draft-then-block procedure (drafting the authorable gaps — acceptance criteria, validation journey, repository, relationship search, etc. — into the ticket as labeled assumptions). What then remains for the human is to **confirm those assumptions** or supply a genuinely human-only input (real missing credentials, an irreducible product/scoping decision). The marker means "a human must confirm or decide," not "a human must author from scratch."
435
463
 
@@ -788,7 +816,7 @@ When `github-to-tracker` is invoked AND `tracker = "github"`, both reads and wri
788
816
 
789
817
  Never overload one label across both lifecycles.
790
818
 
791
- The same separation applies for Linear self-host (`source = "linear"` AND `tracker = "linear"`): project-level labels (`prd-*`) drive the PRD lifecycle; issue-level labels (`status:*`) drive the build lifecycle; the sentinel feedback issue carries the issue-level `prd-intake-feedback` label.
819
+ The same separation applies for Linear self-host (`source = "linear"` AND `tracker = "linear"`), with one asymmetry: project-level **labels** (`prd-*`) drive the PRD lifecycle, because a PRD is a Linear Project and Projects carry their own status object rather than Issue workflow states; issue-level **workflow states** (`linear.workflow`) drive the build lifecycle; the sentinel feedback issue carries the issue-level `prd-intake-feedback` label. So on Linear the two lanes are not merely different vocabularies, they are different *mechanisms* — never move a PRD by state or an Issue by `status:*` label.
792
820
 
793
821
  ## Notion access (substrate ladder)
794
822
 
@@ -31,7 +31,7 @@ History is always obtained through the vendor access layer — never a direct ve
31
31
 
32
32
  - **GitHub** — read the issue via `lisa-github-read-issue`, whose Label-Event History surface returns chronological `LabeledEvent` / `UnlabeledEvent` entries. A backward move is: the configured **ready** label was removed (item advanced) and later re-added (item bounced back). Non-status label churn is ignored for classification.
33
33
  - **JIRA** — call `lisa-atlassian-access operation: changelog key:<K>`. A backward move is a status changelog entry whose `to` is the configured ready status, following an earlier entry that reached a `review`/`done`-ward status.
34
- - **Linear** — call `lisa-linear-access operation: history id:<ID>`, keyed on `status:*` **label** history (Linear build lanes are label-driven — `lisa-linear-build-intake` keys the queue on `status:*` labels). Resolve `addedLabelIds` / `removedLabelIds` against `list-issue-labels`; a backward move is the configured ready label re-added after a later-lane label was applied. Linear workflow-state moves (`fromState`/`toState`) are a secondary corroborating signal where the project maps lanes to states.
34
+ - **Linear** — call `lisa-linear-access operation: history id:<ID>`, keyed on **workflow-state** history (Linear build lanes are state-driven — `lisa-linear-build-intake` keys the queue on `linear.workflow.*`). Each history node inlines `fromState.name` / `toState.name`, so a backward move reads directly: a move back into the configured `ready` state from a later lane. No label-ID resolution, and no reconstruction from lossy `addedLabelIds` / `removedLabelIds` deltas that indirection existed only while the lane was label-driven.
35
35
 
36
36
  ### Lane names are configuration, never literals
37
37
 
@@ -39,7 +39,7 @@ The ready / claimed / done lane names ALWAYS come from `.lisa.config.json` lanes
39
39
 
40
40
  - `github.labels.build.{ready,claimed,done}` (GitHub),
41
41
  - the JIRA status equivalents, and
42
- - the Linear label equivalents,
42
+ - the Linear state equivalents (`linear.workflow.*`),
43
43
 
44
44
  resolved per the `config-resolution` rule with the `src/sync/registry.ts` `BUILD_LABEL_DEFAULTS` (`ready: status:ready`, `claimed: status:in-progress`, `done: {dev: status:on-dev, staging: status:on-stg, production: status:done}`) as the fallback. **Never hardcode** a lane string in the detection logic — a project that renames its ready lane must still detect rejections.
45
45
 
@@ -308,7 +308,7 @@ For each PRD epic, **invoke the `lisa-tracker-write` skill** (do not invoke `lis
308
308
  - `artifacts`: the full Phase 1.5 artifact list — every artifact, regardless of domain. The epic is the canonical hub. No filtering at the epic level.
309
309
  - `priority`, `labels`, `components`, `fix_version`: as appropriate
310
310
 
311
- **Leaf-only build-ready (`leaf-only-lifecycle`)**: an Epic is a container, not a leaf work unit. Do NOT mark it build-ready — `lisa-tracker-write` must not be passed `status:ready` for an Epic, and the Epic's lifecycle state rolls up from its children. The build-ready label is applied only in Phase 5.
311
+ **Leaf-only build-ready (`leaf-only-lifecycle`)**: an Epic is a container, not a leaf work unit. Do NOT mark it build-ready — `lisa-tracker-write` must not be passed the build-ready role for an Epic, and the Epic's lifecycle state rolls up from its children. The build-ready role is applied only in Phase 5.
312
312
 
313
313
  Capture the returned epic key — Phase 4 needs it as the parent for stories.
314
314
 
@@ -339,7 +339,7 @@ For each story, **invoke `lisa-tracker-write`** with:
339
339
  | Infrastructure | `ops`, `reference` |
340
340
  | Mixed / setup ("X.0") | All domains |
341
341
 
342
- **Leaf-only build-ready (`leaf-only-lifecycle`)**: a Story is a container (it has child Sub-tasks), not a leaf work unit. Do NOT mark it build-ready — never pass `status:ready` to `lisa-tracker-write` for a Story. Its lifecycle state rolls up from its Sub-tasks. The build-ready label is applied only in Phase 5.
342
+ **Leaf-only build-ready (`leaf-only-lifecycle`)**: a Story is a container (it has child Sub-tasks), not a leaf work unit. Do NOT mark it build-ready — never pass the build-ready role to `lisa-tracker-write` for a Story. Its lifecycle state rolls up from its Sub-tasks. The build-ready role is applied only in Phase 5.
343
343
 
344
344
  Capture each returned story key — Phase 5 needs it as the parent for sub-tasks.
345
345
 
@@ -356,7 +356,7 @@ Each sub-task MUST:
356
356
  2. **Include an Empirical Verification Plan** — real user-like verification, NOT unit tests, linting, or typechecking
357
357
  3. **Carry its own `## Source Requirement` section** (shared format above) with the full verbatim quote(s) from the Phase 1.4 register — a leaf claimed by build-intake in isolation must be self-explanatory. When a sub-task is split per-repo, every split child inherits the same requirement quote(s).
358
358
 
359
- **Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition — they are the ONLY items in the hierarchy that receive the build-ready label. `lisa-tracker-write` applies `status:ready` here so downstream build intake (`lisa-tracker-build-intake`) claims the leaves and never the Epic or Stories. Apply `status:ready` to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-tracker-write` enforces the same invariant on the write side, so a Sub-task split into per-repo children (the cross-repo case above) carries build-ready on the children, not on any intermediate parent that gains child work.
359
+ **Leaf-only build-ready (`leaf-only-lifecycle`)**: Sub-tasks are the **leaf work units** of the decomposition — they are the ONLY items in the hierarchy that receive the build-ready role. `lisa-tracker-write` applies the build-ready role here so downstream build intake (`lisa-tracker-build-intake`) claims the leaves and never the Epic or Stories. Apply the build-ready role to each Sub-task; never to its parent Story or Epic (Phases 3–4). `lisa-tracker-write` enforces the same invariant on the write side, so a Sub-task split into per-repo children (the cross-repo case above) carries build-ready on the children, not on any intermediate parent that gains child work.
360
360
 
361
361
  Sub-tasks inherit their parent story's artifacts by reference (the parent link). Do not pass the same artifact list to every sub-task.
362
362
 
@@ -46,7 +46,27 @@ What genuinely differs is **consent**, not the list:
46
46
 
47
47
  Omitting `surfaces` means every surface, because that is true of most tools and the cost of forgetting should be a redundant check rather than a silent absence.
48
48
 
49
- A platform-specific pin is the exception worth knowing: a Linux release archive must be `surfaces: ["remote"]`, with a matching `require` entry for `local`, so a laptop asserts the tool without being offered a binary it cannot run.
49
+ Platform differences are **not** expressed with `surfaces`. A downloaded tool declares a
50
+ `platforms` map keyed `<platform>-<arch>`, each block carrying its own `install` method, `url`,
51
+ and `sha256`:
52
+
53
+ ```json
54
+ "platforms": {
55
+ "linux-x64": { "install": "release-tar", "url": "...", "sha256": "..." },
56
+ "darwin-arm64": { "install": "release-zip", "url": "...", "sha256": "..." }
57
+ }
58
+ ```
59
+
60
+ The method lives inside the block because it varies — gh ships a `.tar.gz` for Linux and a
61
+ `.zip` for macOS. A flat entry means one artifact serves everything, which is true of
62
+ `npm-global` and nothing else.
63
+
64
+ This replaces an earlier convention worth naming, because its residue may still be in a
65
+ manifest you read: a Linux archive used to be marked `surfaces: ["remote"]` with a bare
66
+ `require` entry for `local`, so a laptop asserted the tool without being offered a binary it
67
+ could not run. That kept the wrong binary off the laptop by making the tool uninstallable
68
+ there — which is how `bws` and `gh`, the two CLIs Lisa's own guardrails shell out to, came to
69
+ be required on developer machines and provisionable only in containers.
50
70
 
51
71
  ## Usage
52
72
 
@@ -361,9 +361,11 @@ export function detectTooling(cwd = process.cwd()) {
361
361
  /**
362
362
  * The manifest entries an operator can paste, with the parts only they supply.
363
363
  *
364
- * Returns both lists because a platform-specific archive needs both: an
365
- * `install` entry for the surface it is built for, and a `require` entry so the
366
- * other surface still asserts the tool instead of silently ignoring it.
364
+ * A release archive is proposed as a `platforms` map rather than a single URL
365
+ * plus `surfaces: ["remote"]`. The old shape could express only one artifact, so
366
+ * keeping a Linux binary off a laptop meant excluding the tool from laptops
367
+ * altogether — which is how `bws` and `gh` came to be required on a developer
368
+ * machine and installable only in a container.
367
369
  * @param {{name: string}} proposal One detected tool.
368
370
  * @returns {{install: object[], require: object[]}} Manifest skeletons.
369
371
  */
@@ -394,23 +396,33 @@ export function proposedEntries(proposal) {
394
396
  require: [],
395
397
  };
396
398
  }
397
- // A release archive is built for one platform, so it is proposed as
398
- // remote-install plus a local `require`. Proposing only the install entry
399
- // produced a manifest that either offered a Linux binary to a laptop or
400
- // once narrowed to remote stopped checking for the tool locally at all.
401
- // Both halves or neither.
399
+ // A release archive is built for one platform, so every platform the project
400
+ // is developed or built on needs its own block — with its own install method,
401
+ // because a vendor may ship a tarball for one and a zip for another, as gh
402
+ // does. Both containers and laptops are proposed: a tool the manifest can
403
+ // only install remotely is one every developer installs by hand or does
404
+ // without.
405
+ //
406
+ // The placeholders stay unresolved on purpose. A guessed URL is an artifact
407
+ // the checksum cannot vouch for, which is the one property that makes a
408
+ // pinned entry worth reviewing.
409
+ const archive = platform => ({
410
+ install: "<release-tar or release-zip, whichever this platform ships>",
411
+ url: `<release url for this exact version, for ${platform}>`,
412
+ sha256: `<sha256 published with the ${platform} release>`,
413
+ });
402
414
  return {
403
415
  install: [
404
416
  {
405
417
  name: proposal.name,
406
418
  version: "<pin>",
407
- install: "release-tar",
408
- url: "<release url for this exact version, for the remote platform>",
409
- sha256: "<sha256 published with that release>",
410
- surfaces: ["remote"],
419
+ platforms: {
420
+ "linux-x64": archive("linux-x64"),
421
+ "darwin-arm64": archive("darwin-arm64"),
422
+ },
411
423
  },
412
424
  ],
413
- require: [{ name: proposal.name, surfaces: ["local"] }],
425
+ require: [],
414
426
  };
415
427
  }
416
428
 
@@ -251,7 +251,7 @@ PASS (the childless-parent exception) when the issue is build-ready and is a **l
251
251
  | Epic | no | yes | **FAIL** (childless Epic — pure rollup container, exception does not apply) |
252
252
  | any | any | no | **N/A** (not build-ready) |
253
253
 
254
- Remediation (render `<READY_ROLE>` as the resolved configured label, never as a hard-coded default): `"Build-ready (<READY_ROLE>; status:ready by default) is leaf-only per leaf-only-lifecycle. Move <READY_ROLE> off this container onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type); a parent's lifecycle state rolls up from its children and is never set to ready directly."`
254
+ Remediation (render `<READY_ROLE>` as the resolved configured label, never as a hard-coded default): `"Build-ready is leaf-only per leaf-only-lifecycle. Move <READY_ROLE> off this container onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type); a parent's lifecycle state rolls up from its children and is never set to ready directly."`
255
255
 
256
256
  `product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
257
257
 
@@ -189,7 +189,7 @@ The childless-parent exception promotes every childless type **except Epic** to
189
189
  Post via `lisa-atlassian-access` `operation: comment key: <TICKET> body: "<message>"` with:
190
190
 
191
191
  ```text
192
- [claude-build-intake] Not claimed: this ticket carries the build-ready status ($READY) but is a container with open child work (or a childless Epic), which violates the leaf-only-lifecycle rule. Build-ready (status:ready) is leaf-only per leaf-only-lifecycle — an agent claims and implements leaves, never a container. Repair: move $READY off this parent onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type). A parent's lifecycle state rolls up from its children and is never set to ready directly.
192
+ [claude-build-intake] Not claimed: this ticket carries the build-ready status ($READY) but is a container with open child work (or a childless Epic), which violates the leaf-only-lifecycle rule. Build-ready is leaf-only per leaf-only-lifecycle — an agent claims and implements leaves, never a container. Repair: move $READY off this parent onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type). A parent's lifecycle state rolls up from its children and is never set to ready directly.
193
193
  ```
194
194
 
195
195
  This gate never blocks a legitimate flat Task/Bug: those have no open children and a leaf type, so they fall straight through to the claim in 3b.
@@ -252,7 +252,7 @@ PASS (the childless-parent exception) when the ticket is build-ready and is a **
252
252
  | Epic | no | yes | **FAIL** (childless Epic — pure rollup container, exception does not apply) |
253
253
  | any | any | no | **N/A** (not build-ready) |
254
254
 
255
- Remediation: `"Build-ready (status:ready) is leaf-only per leaf-only-lifecycle. Move status:ready off this container onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type); a parent's lifecycle state rolls up from its children and is never set to ready directly."`
255
+ Remediation: `"Build-ready is leaf-only per leaf-only-lifecycle. Move the build-ready role off this container onto its leaf children (or, for a childless Epic, decompose it into leaf children or reclassify it to a leaf type); a parent's lifecycle state rolls up from its children and is never set to ready directly."`
256
256
 
257
257
  `product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
258
258
 
@@ -18,9 +18,11 @@ operation: get-team id:<ID>
18
18
  operation: list-projects [team:<KEY>] [label:<NAME>] [state:<arr>]
19
19
  operation: get-project id:<ID>
20
20
  operation: save-project payload:{...}
21
- operation: list-issues [team:<ID>] [project:<ID>] [label:<NAME>] [state_type:<arr>]
21
+ operation: list-issues [team:<ID>] [project:<ID>] [label:<NAME>] [state:<NAME>] [state_type:<arr>]
22
22
  operation: get-issue id:<ID>
23
23
  operation: save-issue payload:{...}
24
+ operation: list-workflow-states team:<ID>
25
+ operation: create-workflow-state payload:{...}
24
26
  operation: list-comments issue_id:<ID>
25
27
  operation: save-comment issue_id:<ID> body:"..."
26
28
  operation: history id:<ID>
@@ -118,15 +120,24 @@ query($id:String!){
118
120
  `toState.name`, `createdAt` (ISO timestamp), `actor.name`. Nodes with no
119
121
  `fromState`/`toState` are non-state edits (label-only, assignee, etc.); keep
120
122
  them for the label stream, skip them for workflow-state ordering.
121
- - **Label history (honest caveat).** Linear's build lanes are **label-driven**
122
- (`lisa-linear-build-intake` keys the queue on `status:*` labels), so label
123
- moves matter as much as workflow-state moves. `IssueHistory` carries label
124
- changes as `addedLabelIds` / `removedLabelIds` arrays of label **IDs**, not
125
- names. It does **not** inline label names, and it does not carry the label's
126
- full prior/next set only the per-event deltas. Resolve IDs names by
123
+ - **Build lanes are STATE-driven, so the `from`/`to` stream above is the primary
124
+ signal.** `lisa-linear-build-intake` keys the queue on workflow states
125
+ (`linear.workflow`), and `IssueHistory` inlines `fromState.name` /
126
+ `toState.name` directlyno catalog cross-reference, no ID resolution, no
127
+ reconstruction. Callers needing lifecycle transitions read them straight off
128
+ the node. This is strictly better than the label stream below and is why the
129
+ Linear adapter moved to states.
130
+ - **Label history (honest caveat, still needed for MARKERS and the PRD lane).**
131
+ `human_needed` is a label, and the PRD lifecycle rides on project labels, so
132
+ label moves still matter for those. `IssueHistory` carries label changes as
133
+ `addedLabelIds` / `removedLabelIds` — arrays of label **IDs**, not names. It
134
+ does **not** inline label names, and it does not carry the label's full
135
+ prior/next set — only the per-event deltas. Resolve IDs → names by
127
136
  cross-referencing `list-issue-labels`. Do not overclaim: a caller that needs
128
- `status:*` label transitions reconstructs them from the ID deltas plus the
129
- label catalog, not from an inline name on the history node.
137
+ label transitions reconstructs them from the ID deltas plus the label catalog,
138
+ not from an inline name on the history node. A caller reading a **build**
139
+ lifecycle transition should not be in this bullet at all — use the state
140
+ stream.
130
141
  - **Empty is valid.** An Issue that never changed state returns an **empty**
131
142
  history — an empty history is a valid result, not an error.
132
143
  - **Graceful degrade — never block the build.** A failed history fetch returns