@codyswann/lisa 2.33.2 → 2.34.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 (28) hide show
  1. package/dist/codex/plugin-marketplace-installer.d.ts.map +1 -1
  2. package/dist/codex/plugin-marketplace-installer.js +2 -0
  3. package/dist/codex/plugin-marketplace-installer.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  6. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  7. package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +34 -3
  8. package/plugins/lisa/skills/linear-validate-issue/SKILL.md +33 -2
  9. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  10. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  11. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  14. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  15. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  17. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  19. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  23. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  25. package/plugins/lisa-wiki/commands/setup/wiki.md +6 -0
  26. package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +34 -3
  27. package/plugins/src/base/skills/linear-validate-issue/SKILL.md +33 -2
  28. package/plugins/src/wiki/commands/setup/wiki.md +6 -0
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-marketplace-installer.d.ts","sourceRoot":"","sources":["../../src/codex/plugin-marketplace-installer.ts"],"names":[],"mappings":"AAWA,6EAA6E;AAC7E,eAAO,MAAM,sBAAsB,QAIlC,CAAC;AAwBF,2CAA2C;AAC3C,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CAcnC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB"}
1
+ {"version":3,"file":"plugin-marketplace-installer.d.ts","sourceRoot":"","sources":["../../src/codex/plugin-marketplace-installer.ts"],"names":[],"mappings":"AAWA,6EAA6E;AAC7E,eAAO,MAAM,sBAAsB,QAIlC,CAAC;AA0BF,2CAA2C;AAC3C,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;CAChC;AAED;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,wBAAwB,CAAC,CAcnC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkBzB"}
@@ -19,6 +19,7 @@ const LISA_CODEX_PLUGINS = [
19
19
  "lisa-cdk",
20
20
  "lisa-harper-fabric",
21
21
  "lisa-rails",
22
+ "lisa-wiki",
22
23
  ];
23
24
  /** Marketplace category should match each generated `.codex-plugin` manifest. */
24
25
  const LISA_CODEX_PLUGIN_CATEGORIES = {
@@ -29,6 +30,7 @@ const LISA_CODEX_PLUGIN_CATEGORIES = {
29
30
  "lisa-cdk": "Coding",
30
31
  "lisa-harper-fabric": "Coding",
31
32
  "lisa-rails": "Coding",
33
+ "lisa-wiki": "Productivity",
32
34
  };
33
35
  /**
34
36
  * Install or merge Lisa's Codex marketplace entries.
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-marketplace-installer.js","sourceRoot":"","sources":["../../src/codex/plugin-marketplace-installer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,IAAI,CAC7C,SAAS,EACT,SAAS,EACT,kBAAkB,CACnB,CAAC;AAEF,yCAAyC;AACzC,MAAM,kBAAkB,GAAG;IACzB,MAAM;IACN,iBAAiB;IACjB,WAAW;IACX,aAAa;IACb,UAAU;IACV,oBAAoB;IACpB,YAAY;CACJ,CAAC;AAEX,iFAAiF;AACjF,MAAM,4BAA4B,GAAqC;IACrE,IAAI,EAAE,cAAc;IACpB,iBAAiB,EAAE,cAAc;IACjC,WAAW,EAAE,QAAQ;IACrB,aAAa,EAAE,QAAQ;IACvB,UAAU,EAAE,QAAQ;IACpB,oBAAoB,EAAE,QAAQ;IAC9B,YAAY,EAAE,QAAQ;CACvB,CAAC;AAQF;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,OAAe,EACf,OAAe;IAEf,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACnE,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM;QACrB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QACrD,CAAC,CAAC,sBAAsB,EAAE,CAAC;IAC7B,MAAM,MAAM,GAAG,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChE,MAAM,SAAS,CACb,eAAe,EACf,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EACtC,MAAM,CACP,CAAC;IACF,OAAO,EAAE,OAAO,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,kBAAkB,CAAC,MAAM,EAAE,CAAC;AACxE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAiB,EACjB,OAAe,EACf,OAAe;IAEf,MAAM,IAAI,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CACrC,MAAM,CAAC,EAAE,CACP,CAAC,kBAAkB,CAAC,QAAQ,CAC1B,MAAM,CAAC,IAA2C,CACnD,CACJ,CAAC;IACF,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE;YACP,GAAG,WAAW;YACd,GAAG,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CACrC,0BAA0B,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CACzD;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAS,sBAAsB;IAC7B,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,SAAS,EAAE;YACT,WAAW,EAAE,cAAc;SAC5B;QACD,OAAO,EAAE,EAAE;KACZ,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,GAAY;IAKxC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,oBAAoB,CAAC,sBAAsB,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,OAAO;QACL,IAAI,EAAE,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;QACtD,SAAS,EACP,GAAG,CAAC,SAAS,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ;YACzD,CAAC,CAAE,GAAG,CAAC,SAAqC;YAC5C,CAAC,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE;QACrC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;YACjC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAChB,CAAC,MAAM,EAAqC,EAAE,CAC5C,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,CAChD;YACH,CAAC,CAAC,EAAE;KACP,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,0BAA0B,CACjC,UAAkB,EAClB,OAAe,EACf,OAAe;IAEf,OAAO;QACL,IAAI,EAAE,UAAU;QAChB,MAAM,EAAE;YACN,MAAM,EAAE,OAAO;YACf,IAAI,EAAE,yBAAyB,CAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,EACzC,OAAO,CACR;SACF;QACD,MAAM,EAAE;YACN,YAAY,EACV,UAAU,KAAK,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,WAAW;YAC9D,cAAc,EAAE,YAAY;SAC7B;QACD,QAAQ,EAAE,4BAA4B,CAAC,UAAU,CAAC,IAAI,QAAQ;KAC/D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,yBAAyB,CAChC,UAAkB,EAClB,OAAe;IAEf,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC9E,OAAO,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;AAC/D,CAAC"}
1
+ {"version":3,"file":"plugin-marketplace-installer.js","sourceRoot":"","sources":["../../src/codex/plugin-marketplace-installer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -82,7 +82,7 @@
82
82
  "lodash": ">=4.18.1"
83
83
  },
84
84
  "name": "@codyswann/lisa",
85
- "version": "2.33.2",
85
+ "version": "2.34.0",
86
86
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
87
87
  "main": "dist/index.js",
88
88
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -60,9 +60,11 @@ authenticated_surface: true # → requires Sign-in Required
60
60
  artifacts_attached: true # → requires Source Precedence section
61
61
  links: [{ key: "PROJ-99", type: "is blocked by" }] # known issue links (may be empty)
62
62
  remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
63
+ build_ready: true # caller asserts the build-ready role (status:ready) is/would be applied — see S15
64
+ child_refs: ["PROJ-601", "PROJ-602"] # known child work (sub-tasks / "is blocked by" parentage) — see S15
63
65
  ```
64
66
 
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.
67
+ 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 — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-tasks plus `is blocked by` parentage, resolved as in `lisa:jira-read-ticket`) so S15 can classify the ticket — then run gates.
66
68
 
67
69
  ## Gates
68
70
 
@@ -86,6 +88,7 @@ Each gate is tagged with a fixed `category` and a `product_relevant` boolean. Ca
86
88
  | S12 Source Precedence | `design-ux` | true |
87
89
  | S13 Relationship Search | `dependency` | true |
88
90
  | S14 Evidence manifest binding (leaf work units) | `acceptance-criteria` | true |
91
+ | S15 Leaf-only build-ready | `structural` | false |
89
92
  | F1 Issue type valid in project | `structural` | false |
90
93
  | F2 Epic parent exists and is an Epic | `structural` | false |
91
94
  | F3 Linked tickets exist | `structural` | false |
@@ -199,6 +202,33 @@ FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]`
199
202
 
200
203
  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
204
 
205
+ #### S15 — Leaf-only build-ready
206
+
207
+ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only a leaf work unit may carry the build-ready role.** This is the symmetric write-side guard for the JIRA validator — a stale or hand-applied `status:ready` label on a container is a lifecycle error and must FAIL here, regardless of how the ticket was produced. (Mirrors the "Build-ready label is leaf-only" rule that `lisa:jira-write-ticket` applies at write time.)
208
+
209
+ **When the gate applies.** Run S15 whenever the ticket is build-ready — i.e. `build_ready = true`, or the spec/live labels include `status:ready`. If the ticket is not build-ready, S15 is `N/A` (nothing claims a non-ready ticket, so the invariant is vacuous).
210
+
211
+ **Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an item is a **container** if it has child work, whatever its declared type; otherwise the **issue type** decides. Determine child work from (in order) `child_refs`, native sub-tasks, and `is blocked by` / parent references — the same hierarchy resolution `lisa:jira-read-ticket` uses. When validating a live key, query sub-tasks alongside the ticket fetch.
212
+
213
+ Apply this decision and FAIL the two invariant-violating cases:
214
+
215
+ 1. **Container with child work + build-ready** — `issue_type ∈ {Epic, Story, Spike}` OR child work is present (any type that has children), AND build-ready. FAIL. A parent organizes work; it is never claimed and implemented directly. Its lifecycle state rolls up from its children.
216
+ 2. **Childless container-type + build-ready** — `issue_type ∈ {Epic, Story, Spike}` with **no** child work, AND build-ready. Still FAIL: these types are coordination containers by design, and an empty one is an incomplete decomposition, not an implementable unit (the childless-parent exception in `leaf-only-lifecycle` does **not** promote an Epic/Story/Spike to build-ready).
217
+
218
+ PASS (the childless-parent exception) when the ticket is build-ready and is a **leaf work unit**: `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND has **no** child work. A flat Task or Bug with no sub-tasks is a valid build-ready leaf and must not be stranded.
219
+
220
+ | issue_type | has child work | build-ready | S15 |
221
+ |---|---|---|---|
222
+ | Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
223
+ | Bug / Task / Sub-task / Improvement | yes | yes | **FAIL** (structurally a container) |
224
+ | Epic / Story / Spike | yes | yes | **FAIL** (container with children) |
225
+ | Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
226
+ | any | any | no | **N/A** (not build-ready) |
227
+
228
+ 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/Story/Spike, 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."`
229
+
230
+ `product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
231
+
202
232
  ### Feasibility Gates (require JIRA lookups; skip in dry-run if requested)
203
233
 
204
234
  #### F1 — Issue type valid in project
@@ -219,7 +249,7 @@ Use the same project-issue-type-metadata lookup from F1 (via `lisa:atlassian-acc
219
249
 
220
250
  ## Execution
221
251
 
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.
252
+ 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 — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-tasks plus `is blocked by` parentage, resolved as in `lisa:jira-read-ticket`) so S15 can classify the ticket. Otherwise parse the YAML spec.
223
253
  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`).
224
254
  3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
225
255
  4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
@@ -247,6 +277,7 @@ Output is a single fenced text block. Callers parse it; do not add free-form pro
247
277
  - [PASS|FAIL|N/A] S12 Source Precedence — <one-line reason>
248
278
  - [PASS|FAIL|N/A] S13 Relationship Search — <one-line reason>
249
279
  - [PASS|FAIL|N/A] S14 Evidence manifest binding — <one-line reason>
280
+ - [PASS|FAIL|N/A] S15 Leaf-only build-ready — <one-line reason>
250
281
 
251
282
  ### Feasibility Gates (omit this section when --spec-only)
252
283
  - [PASS|FAIL|N/A] F1 Issue type valid in project — <one-line reason>
@@ -271,7 +302,7 @@ The verdict is `PASS` if and only if every applicable gate is `PASS`. Any `FAIL`
271
302
 
272
303
  ### Failure-detail fields
273
304
 
274
- - **gate**: the gate ID (`S1`–`S14`, `F1`–`F4`).
305
+ - **gate**: the gate ID (`S1`–`S15`, `F1`–`F4`).
275
306
  - **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`.
276
307
  - **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.
277
308
  - **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.
@@ -61,9 +61,11 @@ authenticated_surface: true # → requires Sign-in Required
61
61
  artifacts_attached: true # → requires Source Precedence section
62
62
  relations: [{ id: "ENG-99", type: "blocked_by" }] # known issue relations (may be empty)
63
63
  remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
64
+ build_ready: true # caller asserts the build-ready role (status:ready) is/would be applied — see S15
65
+ child_refs: ["ENG-601", "ENG-602"] # known child work (sub-issues / project-member issues / blocked_by parentage) — see S15
64
66
  ```
65
67
 
66
- If the caller passes only an identifier, fetch the item via `mcp__linear-server__get_issue` (Issue) or `mcp__linear-server__get_project` (Project), derive the same fields from the fetched data, then run gates.
68
+ If the caller passes only an identifier, fetch the item via `mcp__linear-server__get_issue` (Issue) or `mcp__linear-server__get_project` (Project), derive the same fields from the fetched data — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa:linear-read-issue`) so S15 can classify the item — then run gates.
67
69
 
68
70
  ## Gates
69
71
 
@@ -87,6 +89,7 @@ Each gate is tagged with a fixed `category` and a `product_relevant` boolean. Ca
87
89
  | S12 Source Precedence | `design-ux` | true |
88
90
  | S13 Relationship Search | `dependency` | true |
89
91
  | S14 Evidence manifest binding (leaf work units) | `acceptance-criteria` | true |
92
+ | S15 Leaf-only build-ready | `structural` | false |
90
93
  | F1 Issue type valid in team | `structural` | false |
91
94
  | F2 Project parent exists and is in same team | `structural` | false |
92
95
  | F3 Linked items exist | `structural` | false |
@@ -200,6 +203,33 @@ FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]`
200
203
 
201
204
  This gate depends on S11. It is `N/A` for Project / 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:linear-add-journey`.
202
205
 
206
+ #### S15 — Leaf-only build-ready
207
+
208
+ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only a leaf work unit may carry the build-ready role.** This is the symmetric write-side guard for the Linear validator — a stale or hand-applied `status:ready` label on a container is a lifecycle error and must FAIL here, regardless of how the item was produced. (Mirrors the "Build-ready label is leaf-only" rule that `lisa:linear-write-issue` applies at write time.)
209
+
210
+ **When the gate applies.** Run S15 whenever the item is build-ready — i.e. `build_ready = true`, or the spec/live labels include `status:ready`. If the item is not build-ready, S15 is `N/A` (nothing claims a non-ready item, so the invariant is vacuous).
211
+
212
+ **Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an item is a **container** if it has child work, whatever its declared type; otherwise the **issue type** decides. Determine child work from (in order) `child_refs`, native sub-issues, project-member issues (an Epic is modeled as a Linear Project), and `blocked_by` / parent references — the same hierarchy resolution `lisa:linear-read-issue` uses. When validating a live identifier, query sub-issues / project members alongside the item fetch.
213
+
214
+ Apply this decision and FAIL the two invariant-violating cases:
215
+
216
+ 1. **Container with child work + build-ready** — `issue_type ∈ {Epic, Story, Spike}` OR child work is present (any type that has children), AND build-ready. FAIL. A parent organizes work; it is never claimed and implemented directly. Its lifecycle state rolls up from its children.
217
+ 2. **Childless container-type + build-ready** — `issue_type ∈ {Epic, Story, Spike}` with **no** child work, AND build-ready. Still FAIL: these types are coordination containers by design, and an empty one is an incomplete decomposition, not an implementable unit (the childless-parent exception in `leaf-only-lifecycle` does **not** promote an Epic/Story/Spike to build-ready).
218
+
219
+ PASS (the childless-parent exception) when the item is build-ready and is a **leaf work unit**: `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND has **no** child work. A flat Task or Bug with no sub-issues is a valid build-ready leaf and must not be stranded.
220
+
221
+ | issue_type | has child work | build-ready | S15 |
222
+ |---|---|---|---|
223
+ | Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
224
+ | Bug / Task / Sub-task / Improvement | yes | yes | **FAIL** (structurally a container) |
225
+ | Epic / Story / Spike | yes | yes | **FAIL** (container with children) |
226
+ | Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
227
+ | any | any | no | **N/A** (not build-ready) |
228
+
229
+ 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/Story/Spike, 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."`
230
+
231
+ `product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
232
+
203
233
  ### Feasibility Gates (require Linear lookups; skip in dry-run if requested)
204
234
 
205
235
  #### F1 — Issue type valid in team
@@ -224,7 +254,7 @@ For each label referenced (`status:*`, `component:<name>`, `prd-*`), confirm via
224
254
 
225
255
  ## Execution
226
256
 
227
- 1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields. Otherwise parse the YAML spec.
257
+ 1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa:linear-read-issue`) so S15 can classify the item. Otherwise parse the YAML spec.
228
258
  2. Resolve team ID via `mcp__linear-server__list_teams({query: <teamKey>})` if any feasibility gate will run.
229
259
  3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
230
260
  4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
@@ -252,6 +282,7 @@ Output is a single fenced text block. Callers parse it; do not add free-form pro
252
282
  - [PASS|FAIL|N/A] S12 Source Precedence — <one-line reason>
253
283
  - [PASS|FAIL|N/A] S13 Relationship Search — <one-line reason>
254
284
  - [PASS|FAIL|N/A] S14 Evidence manifest binding — <one-line reason>
285
+ - [PASS|FAIL|N/A] S15 Leaf-only build-ready — <one-line reason>
255
286
 
256
287
  ### Feasibility Gates (omit when --spec-only)
257
288
  - [PASS|FAIL|N/A] F1 Issue type valid in team — <one-line reason>
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.33.2",
3
+ "version": "2.34.0",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Scaffold, repair, verify, or upgrade the project's LLM Wiki from its config. Alias for lisa-wiki setup in the Lisa setup command family."
3
+ argument-hint: "[--upgrade] [--with-ci]"
4
+ ---
5
+
6
+ Use the lisa-wiki-setup skill to bring the wiki into conformance from wiki/lisa-wiki.config.json: validate config, ask purpose + README mode, scaffold the canonical structure, render the contract snapshot (stamping kernelVersion), seed the staff roster, then verify with /doctor. $ARGUMENTS
@@ -60,9 +60,11 @@ authenticated_surface: true # → requires Sign-in Required
60
60
  artifacts_attached: true # → requires Source Precedence section
61
61
  links: [{ key: "PROJ-99", type: "is blocked by" }] # known issue links (may be empty)
62
62
  remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
63
+ build_ready: true # caller asserts the build-ready role (status:ready) is/would be applied — see S15
64
+ child_refs: ["PROJ-601", "PROJ-602"] # known child work (sub-tasks / "is blocked by" parentage) — see S15
63
65
  ```
64
66
 
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.
67
+ 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 — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-tasks plus `is blocked by` parentage, resolved as in `lisa:jira-read-ticket`) so S15 can classify the ticket — then run gates.
66
68
 
67
69
  ## Gates
68
70
 
@@ -86,6 +88,7 @@ Each gate is tagged with a fixed `category` and a `product_relevant` boolean. Ca
86
88
  | S12 Source Precedence | `design-ux` | true |
87
89
  | S13 Relationship Search | `dependency` | true |
88
90
  | S14 Evidence manifest binding (leaf work units) | `acceptance-criteria` | true |
91
+ | S15 Leaf-only build-ready | `structural` | false |
89
92
  | F1 Issue type valid in project | `structural` | false |
90
93
  | F2 Epic parent exists and is an Epic | `structural` | false |
91
94
  | F3 Linked tickets exist | `structural` | false |
@@ -199,6 +202,33 @@ FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]`
199
202
 
200
203
  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
204
 
205
+ #### S15 — Leaf-only build-ready
206
+
207
+ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only a leaf work unit may carry the build-ready role.** This is the symmetric write-side guard for the JIRA validator — a stale or hand-applied `status:ready` label on a container is a lifecycle error and must FAIL here, regardless of how the ticket was produced. (Mirrors the "Build-ready label is leaf-only" rule that `lisa:jira-write-ticket` applies at write time.)
208
+
209
+ **When the gate applies.** Run S15 whenever the ticket is build-ready — i.e. `build_ready = true`, or the spec/live labels include `status:ready`. If the ticket is not build-ready, S15 is `N/A` (nothing claims a non-ready ticket, so the invariant is vacuous).
210
+
211
+ **Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an item is a **container** if it has child work, whatever its declared type; otherwise the **issue type** decides. Determine child work from (in order) `child_refs`, native sub-tasks, and `is blocked by` / parent references — the same hierarchy resolution `lisa:jira-read-ticket` uses. When validating a live key, query sub-tasks alongside the ticket fetch.
212
+
213
+ Apply this decision and FAIL the two invariant-violating cases:
214
+
215
+ 1. **Container with child work + build-ready** — `issue_type ∈ {Epic, Story, Spike}` OR child work is present (any type that has children), AND build-ready. FAIL. A parent organizes work; it is never claimed and implemented directly. Its lifecycle state rolls up from its children.
216
+ 2. **Childless container-type + build-ready** — `issue_type ∈ {Epic, Story, Spike}` with **no** child work, AND build-ready. Still FAIL: these types are coordination containers by design, and an empty one is an incomplete decomposition, not an implementable unit (the childless-parent exception in `leaf-only-lifecycle` does **not** promote an Epic/Story/Spike to build-ready).
217
+
218
+ PASS (the childless-parent exception) when the ticket is build-ready and is a **leaf work unit**: `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND has **no** child work. A flat Task or Bug with no sub-tasks is a valid build-ready leaf and must not be stranded.
219
+
220
+ | issue_type | has child work | build-ready | S15 |
221
+ |---|---|---|---|
222
+ | Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
223
+ | Bug / Task / Sub-task / Improvement | yes | yes | **FAIL** (structurally a container) |
224
+ | Epic / Story / Spike | yes | yes | **FAIL** (container with children) |
225
+ | Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
226
+ | any | any | no | **N/A** (not build-ready) |
227
+
228
+ 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/Story/Spike, 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."`
229
+
230
+ `product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
231
+
202
232
  ### Feasibility Gates (require JIRA lookups; skip in dry-run if requested)
203
233
 
204
234
  #### F1 — Issue type valid in project
@@ -219,7 +249,7 @@ Use the same project-issue-type-metadata lookup from F1 (via `lisa:atlassian-acc
219
249
 
220
250
  ## Execution
221
251
 
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.
252
+ 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 — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-tasks plus `is blocked by` parentage, resolved as in `lisa:jira-read-ticket`) so S15 can classify the ticket. Otherwise parse the YAML spec.
223
253
  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`).
224
254
  3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
225
255
  4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
@@ -247,6 +277,7 @@ Output is a single fenced text block. Callers parse it; do not add free-form pro
247
277
  - [PASS|FAIL|N/A] S12 Source Precedence — <one-line reason>
248
278
  - [PASS|FAIL|N/A] S13 Relationship Search — <one-line reason>
249
279
  - [PASS|FAIL|N/A] S14 Evidence manifest binding — <one-line reason>
280
+ - [PASS|FAIL|N/A] S15 Leaf-only build-ready — <one-line reason>
250
281
 
251
282
  ### Feasibility Gates (omit this section when --spec-only)
252
283
  - [PASS|FAIL|N/A] F1 Issue type valid in project — <one-line reason>
@@ -271,7 +302,7 @@ The verdict is `PASS` if and only if every applicable gate is `PASS`. Any `FAIL`
271
302
 
272
303
  ### Failure-detail fields
273
304
 
274
- - **gate**: the gate ID (`S1`–`S14`, `F1`–`F4`).
305
+ - **gate**: the gate ID (`S1`–`S15`, `F1`–`F4`).
275
306
  - **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`.
276
307
  - **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.
277
308
  - **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.
@@ -61,9 +61,11 @@ authenticated_surface: true # → requires Sign-in Required
61
61
  artifacts_attached: true # → requires Source Precedence section
62
62
  relations: [{ id: "ENG-99", type: "blocked_by" }] # known issue relations (may be empty)
63
63
  remote_links: [{ url: "https://github.com/...", title: "PR #42" }]
64
+ build_ready: true # caller asserts the build-ready role (status:ready) is/would be applied — see S15
65
+ child_refs: ["ENG-601", "ENG-602"] # known child work (sub-issues / project-member issues / blocked_by parentage) — see S15
64
66
  ```
65
67
 
66
- If the caller passes only an identifier, fetch the item via `mcp__linear-server__get_issue` (Issue) or `mcp__linear-server__get_project` (Project), derive the same fields from the fetched data, then run gates.
68
+ If the caller passes only an identifier, fetch the item via `mcp__linear-server__get_issue` (Issue) or `mcp__linear-server__get_project` (Project), derive the same fields from the fetched data — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa:linear-read-issue`) so S15 can classify the item — then run gates.
67
69
 
68
70
  ## Gates
69
71
 
@@ -87,6 +89,7 @@ Each gate is tagged with a fixed `category` and a `product_relevant` boolean. Ca
87
89
  | S12 Source Precedence | `design-ux` | true |
88
90
  | S13 Relationship Search | `dependency` | true |
89
91
  | S14 Evidence manifest binding (leaf work units) | `acceptance-criteria` | true |
92
+ | S15 Leaf-only build-ready | `structural` | false |
90
93
  | F1 Issue type valid in team | `structural` | false |
91
94
  | F2 Project parent exists and is in same team | `structural` | false |
92
95
  | F3 Linked items exist | `structural` | false |
@@ -200,6 +203,33 @@ FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]`
200
203
 
201
204
  This gate depends on S11. It is `N/A` for Project / 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:linear-add-journey`.
202
205
 
206
+ #### S15 — Leaf-only build-ready
207
+
208
+ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only a leaf work unit may carry the build-ready role.** This is the symmetric write-side guard for the Linear validator — a stale or hand-applied `status:ready` label on a container is a lifecycle error and must FAIL here, regardless of how the item was produced. (Mirrors the "Build-ready label is leaf-only" rule that `lisa:linear-write-issue` applies at write time.)
209
+
210
+ **When the gate applies.** Run S15 whenever the item is build-ready — i.e. `build_ready = true`, or the spec/live labels include `status:ready`. If the item is not build-ready, S15 is `N/A` (nothing claims a non-ready item, so the invariant is vacuous).
211
+
212
+ **Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an item is a **container** if it has child work, whatever its declared type; otherwise the **issue type** decides. Determine child work from (in order) `child_refs`, native sub-issues, project-member issues (an Epic is modeled as a Linear Project), and `blocked_by` / parent references — the same hierarchy resolution `lisa:linear-read-issue` uses. When validating a live identifier, query sub-issues / project members alongside the item fetch.
213
+
214
+ Apply this decision and FAIL the two invariant-violating cases:
215
+
216
+ 1. **Container with child work + build-ready** — `issue_type ∈ {Epic, Story, Spike}` OR child work is present (any type that has children), AND build-ready. FAIL. A parent organizes work; it is never claimed and implemented directly. Its lifecycle state rolls up from its children.
217
+ 2. **Childless container-type + build-ready** — `issue_type ∈ {Epic, Story, Spike}` with **no** child work, AND build-ready. Still FAIL: these types are coordination containers by design, and an empty one is an incomplete decomposition, not an implementable unit (the childless-parent exception in `leaf-only-lifecycle` does **not** promote an Epic/Story/Spike to build-ready).
218
+
219
+ PASS (the childless-parent exception) when the item is build-ready and is a **leaf work unit**: `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND has **no** child work. A flat Task or Bug with no sub-issues is a valid build-ready leaf and must not be stranded.
220
+
221
+ | issue_type | has child work | build-ready | S15 |
222
+ |---|---|---|---|
223
+ | Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
224
+ | Bug / Task / Sub-task / Improvement | yes | yes | **FAIL** (structurally a container) |
225
+ | Epic / Story / Spike | yes | yes | **FAIL** (container with children) |
226
+ | Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
227
+ | any | any | no | **N/A** (not build-ready) |
228
+
229
+ 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/Story/Spike, 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."`
230
+
231
+ `product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
232
+
203
233
  ### Feasibility Gates (require Linear lookups; skip in dry-run if requested)
204
234
 
205
235
  #### F1 — Issue type valid in team
@@ -224,7 +254,7 @@ For each label referenced (`status:*`, `component:<name>`, `prd-*`), confirm via
224
254
 
225
255
  ## Execution
226
256
 
227
- 1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields. Otherwise parse the YAML spec.
257
+ 1. Parse `$ARGUMENTS`. If it's an identifier, fetch the item and derive the spec from the fetched fields — including `build_ready` (label set contains `status:ready`) and `child_refs` (sub-issues, project-member issues, plus `blocked_by` parentage, resolved as in `lisa:linear-read-issue`) so S15 can classify the item. Otherwise parse the YAML spec.
228
258
  2. Resolve team ID via `mcp__linear-server__list_teams({query: <teamKey>})` if any feasibility gate will run.
229
259
  3. Run every Specification gate in order. Collect PASS / FAIL / N/A with a one-line reason.
230
260
  4. Unless the caller passed `--spec-only` (dry-run), run every Feasibility gate. Collect results.
@@ -252,6 +282,7 @@ Output is a single fenced text block. Callers parse it; do not add free-form pro
252
282
  - [PASS|FAIL|N/A] S12 Source Precedence — <one-line reason>
253
283
  - [PASS|FAIL|N/A] S13 Relationship Search — <one-line reason>
254
284
  - [PASS|FAIL|N/A] S14 Evidence manifest binding — <one-line reason>
285
+ - [PASS|FAIL|N/A] S15 Leaf-only build-ready — <one-line reason>
255
286
 
256
287
  ### Feasibility Gates (omit when --spec-only)
257
288
  - [PASS|FAIL|N/A] F1 Issue type valid in team — <one-line reason>
@@ -0,0 +1,6 @@
1
+ ---
2
+ description: "Scaffold, repair, verify, or upgrade the project's LLM Wiki from its config. Alias for lisa-wiki setup in the Lisa setup command family."
3
+ argument-hint: "[--upgrade] [--with-ci]"
4
+ ---
5
+
6
+ Use the lisa-wiki-setup skill to bring the wiki into conformance from wiki/lisa-wiki.config.json: validate config, ask purpose + README mode, scaffold the canonical structure, render the contract snapshot (stamping kernelVersion), seed the staff roster, then verify with /doctor. $ARGUMENTS