@codyswann/lisa 2.127.0 → 2.127.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/rules/eager/base-rules.md +1 -1
- package/plugins/lisa/rules/eager/leaf-only-lifecycle.md +4 -4
- package/plugins/lisa/rules/eager/repo-scope-split.md +1 -1
- package/plugins/lisa/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +9 -9
- package/plugins/lisa/rules/reference/repo-scope-split.md +2 -2
- package/plugins/lisa/skills/github-build-intake/SKILL.md +7 -7
- package/plugins/lisa/skills/github-validate-issue/SKILL.md +10 -11
- package/plugins/lisa/skills/intake-explain/SKILL.md +3 -3
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +7 -7
- package/plugins/lisa/skills/jira-validate-ticket/SKILL.md +10 -11
- package/plugins/lisa/skills/linear-build-intake/SKILL.md +7 -7
- package/plugins/lisa/skills/linear-validate-issue/SKILL.md +10 -11
- package/plugins/lisa/skills/repair-intake/SKILL.md +2 -2
- package/plugins/lisa/skills/tracker-build-intake/SKILL.md +4 -4
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/github-build-intake/SKILL.md +7 -7
- package/plugins/lisa-agy/skills/github-validate-issue/SKILL.md +10 -11
- package/plugins/lisa-agy/skills/intake-explain/SKILL.md +3 -3
- package/plugins/lisa-agy/skills/jira-build-intake/SKILL.md +7 -7
- package/plugins/lisa-agy/skills/jira-validate-ticket/SKILL.md +10 -11
- package/plugins/lisa-agy/skills/linear-build-intake/SKILL.md +7 -7
- package/plugins/lisa-agy/skills/linear-validate-issue/SKILL.md +10 -11
- package/plugins/lisa-agy/skills/repair-intake/SKILL.md +2 -2
- package/plugins/lisa-agy/skills/tracker-build-intake/SKILL.md +4 -4
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/rules/eager/base-rules.md +1 -1
- package/plugins/lisa-copilot/rules/eager/leaf-only-lifecycle.md +4 -4
- package/plugins/lisa-copilot/rules/eager/repo-scope-split.md +1 -1
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +9 -9
- package/plugins/lisa-copilot/rules/reference/repo-scope-split.md +2 -2
- package/plugins/lisa-copilot/skills/github-build-intake/SKILL.md +7 -7
- package/plugins/lisa-copilot/skills/github-validate-issue/SKILL.md +10 -11
- package/plugins/lisa-copilot/skills/intake-explain/SKILL.md +3 -3
- package/plugins/lisa-copilot/skills/jira-build-intake/SKILL.md +7 -7
- package/plugins/lisa-copilot/skills/jira-validate-ticket/SKILL.md +10 -11
- package/plugins/lisa-copilot/skills/linear-build-intake/SKILL.md +7 -7
- package/plugins/lisa-copilot/skills/linear-validate-issue/SKILL.md +10 -11
- package/plugins/lisa-copilot/skills/repair-intake/SKILL.md +2 -2
- package/plugins/lisa-copilot/skills/tracker-build-intake/SKILL.md +4 -4
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/base-rules.mdc +1 -1
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +9 -9
- package/plugins/lisa-cursor/rules/leaf-only-lifecycle.mdc +4 -4
- package/plugins/lisa-cursor/rules/repo-scope-split-reference.mdc +2 -2
- package/plugins/lisa-cursor/rules/repo-scope-split.mdc +1 -1
- package/plugins/lisa-cursor/skills/github-build-intake/SKILL.md +7 -7
- package/plugins/lisa-cursor/skills/github-validate-issue/SKILL.md +10 -11
- package/plugins/lisa-cursor/skills/intake-explain/SKILL.md +3 -3
- package/plugins/lisa-cursor/skills/jira-build-intake/SKILL.md +7 -7
- package/plugins/lisa-cursor/skills/jira-validate-ticket/SKILL.md +10 -11
- package/plugins/lisa-cursor/skills/linear-build-intake/SKILL.md +7 -7
- package/plugins/lisa-cursor/skills/linear-validate-issue/SKILL.md +10 -11
- package/plugins/lisa-cursor/skills/repair-intake/SKILL.md +2 -2
- package/plugins/lisa-cursor/skills/tracker-build-intake/SKILL.md +4 -4
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/eager/base-rules.md +1 -1
- package/plugins/src/base/rules/eager/leaf-only-lifecycle.md +4 -4
- package/plugins/src/base/rules/eager/repo-scope-split.md +1 -1
- package/plugins/src/base/rules/reference/config-resolution.md +1 -1
- package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +9 -9
- package/plugins/src/base/rules/reference/repo-scope-split.md +2 -2
- package/plugins/src/base/skills/github-build-intake/SKILL.md +7 -7
- package/plugins/src/base/skills/github-validate-issue/SKILL.md +10 -11
- package/plugins/src/base/skills/intake-explain/SKILL.md +3 -3
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +7 -7
- package/plugins/src/base/skills/jira-validate-ticket/SKILL.md +10 -11
- package/plugins/src/base/skills/linear-build-intake/SKILL.md +7 -7
- package/plugins/src/base/skills/linear-validate-issue/SKILL.md +10 -11
- package/plugins/src/base/skills/repair-intake/SKILL.md +2 -2
- package/plugins/src/base/skills/tracker-build-intake/SKILL.md +4 -4
package/package.json
CHANGED
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"lodash": ">=4.18.1"
|
|
84
84
|
},
|
|
85
85
|
"name": "@codyswann/lisa",
|
|
86
|
-
"version": "2.127.
|
|
86
|
+
"version": "2.127.1",
|
|
87
87
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
88
88
|
"main": "dist/index.js",
|
|
89
89
|
"exports": {
|
|
@@ -43,7 +43,7 @@ Do not begin work if there are blockers, ambiguities, access requirements, or un
|
|
|
43
43
|
- Read **all** comments on a ticket, not just the description.
|
|
44
44
|
- When clarifying, comment via ADF and @mention the Reporter.
|
|
45
45
|
- Establish issue link relationships (`blocks`, `is blocked by`, `relates to`) — search git history AND Jira before declaring "no related work."
|
|
46
|
-
- Single-repo invariant: Bug/Task/Sub-task MUST be single-repo. Epic
|
|
46
|
+
- Single-repo invariant: Bug/Task/Sub-task/Improvement (and any childless Story/Spike — a leaf per `leaf-only-lifecycle`) MUST be single-repo. An Epic, or any Story/Spike that still holds child work, MAY span repos. Cross-repo leaves are split per the `repo-scope-split` rule.
|
|
47
47
|
- Pre-flight gate: BLOCK + reassign-to-Reporter if a ticket is missing target backend env, sign-in credentials, Gherkin acceptance criteria, epic parent (non-bug/non-epic), or relationship discovery evidence.
|
|
48
48
|
|
|
49
49
|
## Pace
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Build-ready means a directly implementable leaf work unit.** Containers never carry build-ready.
|
|
4
4
|
|
|
5
|
-
A leaf is structurally defined: **no
|
|
5
|
+
A leaf is structurally defined: **no open children** AND not an Epic — the by-design leaf types (Bug, Task, Sub-task, Improvement) plus a childless Story or Spike. A container is an **Epic**, or any item of any type that has acquired open child work.
|
|
6
6
|
|
|
7
7
|
## Invariant
|
|
8
8
|
|
|
@@ -12,10 +12,10 @@ A leaf is structurally defined: **no child work** AND a leaf-typed item (Bug, Ta
|
|
|
12
12
|
|
|
13
13
|
## Childless-parent exception
|
|
14
14
|
|
|
15
|
-
A
|
|
15
|
+
A childless item is structurally a leaf — and may be build-ready **unless its type is Epic**:
|
|
16
16
|
|
|
17
|
-
- **Task or
|
|
18
|
-
- **Epic
|
|
17
|
+
- **Task, Bug, Story, Spike, or Improvement with no children** → leaf → may be build-ready. A Story ships directly as one increment and a Spike *is* the investigation unit; neither needs sub-items to be implementable, so a childless one must not be stranded.
|
|
18
|
+
- **Epic with no children** → still NOT build-ready. An Epic is a pure rollup container by design — its body is a high-level summary, never directly implementable — so a childless build-ready Epic is an incomplete decomposition or a mis-applied role. Repair: decompose into leaves, or reclassify to a leaf type.
|
|
19
19
|
|
|
20
20
|
## Parent state rollup (priority order, first match wins)
|
|
21
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Repo Scope & Work-Time Splitting (load-bearing)
|
|
2
2
|
|
|
3
|
-
**Leaf work units are single-repo.** A leaf is an individually implementable ticket with no children — types **Bug, Task, Sub-task, Improvement
|
|
3
|
+
**Leaf work units are single-repo.** A leaf is an individually implementable ticket with no open children — the by-design leaf types **Bug, Task, Sub-task, Improvement**, plus a childless **Story** or **Spike** (structurally a leaf per `leaf-only-lifecycle`). Each names exactly one repo. An **Epic**, and any **Story/Spike that still holds child work**, are coordination containers and may span repos.
|
|
4
4
|
|
|
5
5
|
Enforced at four points: gate **S10** (`*-validate-*`, write time), `task-decomposition` step 1.5 (PRD-decomposition time), claim-time repo scoping (`*-build-intake`), and the work-time split procedure (an existing ticket about to be implemented).
|
|
6
6
|
|
|
@@ -647,7 +647,7 @@ A ticketing system can oversee **multiple repos** — e.g. one JIRA project (or
|
|
|
647
647
|
|
|
648
648
|
### The `repo:<name>` label (the repo marker)
|
|
649
649
|
|
|
650
|
-
A work item's target repo is recorded as a **label** `repo:<name>`, where `<name>` is the repo's short name (e.g. `repo:frontend`). The convention is uniform across trackers (JIRA / GitHub / Linear), consistent with the other namespaced labels (`status:`, `type:`, `component:`). On JIRA a **component** equal to the repo name is accepted as an alias (matches the legacy `component = "frontend"` JQL pattern). A leaf work unit carries **exactly one** `repo:<name>` (leaves are single-repo per `repo-scope-split`); a container (Epic
|
|
650
|
+
A work item's target repo is recorded as a **label** `repo:<name>`, where `<name>` is the repo's short name (e.g. `repo:frontend`). The convention is uniform across trackers (JIRA / GitHub / Linear), consistent with the other namespaced labels (`status:`, `type:`, `component:`). On JIRA a **component** equal to the repo name is accepted as an alias (matches the legacy `component = "frontend"` JQL pattern). A leaf work unit carries **exactly one** `repo:<name>` (leaves are single-repo per `repo-scope-split`); a container (an Epic, or any item with open child work) may carry several or none.
|
|
651
651
|
|
|
652
652
|
The label is not required to exist up front: build-intake **determines** the target repo from the ticket's content + code surfaces when the label is absent and **stamps** `repo:<name>` so later cycles filter cheaply (see `repo-scope-split` "claim-time repo scoping").
|
|
653
653
|
|
|
@@ -16,16 +16,16 @@ The fix is not vendor-specific. It belongs here, in a cross-vendor rule, and eve
|
|
|
16
16
|
|
|
17
17
|
## Container vs. leaf taxonomy
|
|
18
18
|
|
|
19
|
-
A **leaf work unit** is an individually implementable item with **no child work
|
|
19
|
+
A **leaf work unit** is an individually implementable item with **no open child work**. Structurally, that is *any work item with no open children except an Epic*: the by-design leaf types **Bug, Task, Sub-task, Improvement**, plus a **childless Story or Spike** (a Story is a directly shippable increment and a Spike is itself the investigation unit — neither needs sub-items to be implementable). These are what an agent claims and implements. A leaf work unit is also single-repo (the `repo-scope-split` rule).
|
|
20
20
|
|
|
21
21
|
A **container** organizes other work and is never directly implemented:
|
|
22
22
|
|
|
23
23
|
| Class | Examples by type | May carry build-ready? |
|
|
24
24
|
|---|---|---|
|
|
25
|
-
| **Leaf work unit** | Bug, Task, Sub-task, Improvement — with no children | **Yes** |
|
|
26
|
-
| **Container** | Epic
|
|
25
|
+
| **Leaf work unit** | Bug, Task, Sub-task, Improvement, or a childless Story / Spike — anything with no open children **except an Epic** | **Yes** |
|
|
26
|
+
| **Container** | An **Epic**, or *any* item (of any type) that has open child work | **No** — state rolls up from children |
|
|
27
27
|
|
|
28
|
-
The classification is **structural, not nominal**: an item is a container if it has child work, regardless of its declared type. A "Task" that has acquired sub-tasks is a container for rollup purposes. The
|
|
28
|
+
The classification is **structural, not nominal**: an item is a container if it has open child work, regardless of its declared type. A "Task" that has acquired sub-tasks is a container for rollup purposes. The single nominal exception is the **Epic**, which is a pure rollup container by design and is treated as a container even when childless; for every other type the presence of children is decisive. See the childless-parent exception below for the converse case.
|
|
29
29
|
|
|
30
30
|
### How each vendor encodes hierarchy
|
|
31
31
|
|
|
@@ -49,12 +49,12 @@ The permission boundary is the maintainer-applied build-ready role, not authorsh
|
|
|
49
49
|
|
|
50
50
|
## Childless-parent exception
|
|
51
51
|
|
|
52
|
-
A
|
|
52
|
+
A childless item is, structurally, a leaf — and may be build-ready **unless its issue type is Epic**.
|
|
53
53
|
|
|
54
|
-
- A **Task
|
|
55
|
-
- An **Epic
|
|
54
|
+
- A **Task, Bug, Story, Spike,** or **Improvement** with no children → leaf → may be build-ready. Many real tickets are flat Tasks with no sub-tasks; just as common, a **Story** is implemented directly as a single shippable increment and a **Spike** *is* the investigation work unit. None of these need to be decomposed to be claimable, and this rule must not strand them. (A childless Story/Spike promoted to a leaf this way is single-repo like any other leaf — see `repo-scope-split`.)
|
|
55
|
+
- An **Epic** with no children → still **not** build-ready. An Epic is a pure rollup container by design: its body is a high-level summary, never a directly implementable unit, so a childless Epic carrying the build-ready role is an incomplete decomposition or a mis-applied role — not work. The correct repair is to decompose it (add leaf children) or reclassify it to a leaf type — not to claim it.
|
|
56
56
|
|
|
57
|
-
So the exception is narrow: childlessness
|
|
57
|
+
So the exception is narrow only at the top: childlessness promotes every type **except Epic** to a build-ready leaf. A childless Epic is never directly implementable; everything else, when childless, is.
|
|
58
58
|
|
|
59
59
|
## Parent status rollup (the state machine)
|
|
60
60
|
|
|
@@ -112,7 +112,7 @@ This action is **terminal-only**:
|
|
|
112
112
|
Skills that enforce this invariant or perform rollup cite this rule by slug (the `leaf-only-lifecycle` rule) instead of restating it:
|
|
113
113
|
|
|
114
114
|
- **Decomposition / write** (`*-to-tracker`, `*-write-*`) — apply the `ready` role to leaves only; never to containers.
|
|
115
|
-
- **Validate** (`*-validate-*`) — FAIL a container carrying the build-ready role; FAIL a childless Epic
|
|
115
|
+
- **Validate** (`*-validate-*`) — FAIL a container carrying the build-ready role; FAIL a childless **Epic** marked build-ready (a childless Story/Spike is a valid leaf and passes).
|
|
116
116
|
- **Build intake** (`*-build-intake`, `tracker-build-intake`) — dispatch leaves only; move or safe-block containers with stale build-ready roles according to vendor lifecycle semantics.
|
|
117
117
|
- **Rollup** — derive parent state from children per the state machine above. `repair-intake`
|
|
118
118
|
also uses this rule to close out parent/container rollups that were left open after every
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Repo Scope & Work-Time Splitting
|
|
2
2
|
|
|
3
|
-
Leaf work units are single-repo. A **leaf work unit** is an individually implementable ticket with no child tickets —
|
|
3
|
+
Leaf work units are single-repo. A **leaf work unit** is an individually implementable ticket with no open child tickets — the by-design leaf types **Bug, Task, Sub-task, Improvement**, plus a childless **Story** or **Spike** (a childless Story/Spike is structurally a leaf — see `leaf-only-lifecycle`). Each must name exactly one repository. An **Epic**, and any **Story or Spike that still holds child work**, are coordination containers and may span repos.
|
|
4
4
|
|
|
5
5
|
This invariant is enforced at four points: gate **S10** in the `*-validate-*` skills (write time), `task-decomposition` step 1.5 (PRD-decomposition time), **claim-time repo scoping** in the build-intake skills (when intake decides whether to claim a ready ticket for the current repo — see below), and the work-time split procedure below (when an agent picks up an existing ticket to implement it).
|
|
6
6
|
|
|
@@ -47,7 +47,7 @@ Resolve the current repo per the `config-resolution` "Repo scoping" section (con
|
|
|
47
47
|
|
|
48
48
|
**Cost.** Only **unlabeled** candidates need content determination; once stamped, wrong-repo candidates are skipped by label alone. Prefer candidates already labeled `repo:<current>` first (cheap claim), falling through to unlabeled candidates (determine + stamp) only when no pre-labeled current-repo leaf is ready.
|
|
49
49
|
|
|
50
|
-
A container (Epic
|
|
50
|
+
A container (an Epic, or any item with open child work) is handled by the leaf-only gate, not here — containers may span repos, may keep multiple `repo:<name>` labels for visibility, and are never claimed/built directly. Only a leaf work unit — including a now-childless Story/Spike that the leaf-only gate treats as a leaf — is split or skipped by repo scope.
|
|
51
51
|
|
|
52
52
|
## Vendor mechanics
|
|
53
53
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: github-build-intake
|
|
3
|
-
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, processes the first eligible issue, runs leaf work via lisa:github-agent, relabels to the configured `done` label on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic
|
|
3
|
+
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, processes the first eligible issue, runs leaf work via lisa:github-agent, relabels to the configured `done` label on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic) that still carries a stale build-ready label is moved out of the ready pickup queue into the configured `claimed` label with a lifecycle-repair comment, never dispatched to lisa:github-agent. The `ready` label is the human-flipped signal that an issue is truly ready for direct development pickup — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
4
4
|
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -209,16 +209,16 @@ Classify and act (first match wins). `type:` is read from the issue's labels (`t
|
|
|
209
209
|
| Condition | Class | Action |
|
|
210
210
|
|---|---|---|
|
|
211
211
|
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
212
|
-
| no open children AND `type
|
|
213
|
-
| no open children AND `type
|
|
212
|
+
| no open children AND `type = Epic` | **Childless Epic (pure rollup container)** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
213
|
+
| no open children AND `type ≠ Epic` (Bug, Task, Sub-task, Improvement, Story, Spike, or no `type:` label) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
214
214
|
|
|
215
|
-
The childless-parent exception
|
|
215
|
+
The childless-parent exception promotes every childless type **except Epic** to a dispatchable leaf: a childless Story is a directly shippable increment and a childless Spike *is* the investigation unit, so neither is stranded. Only a childless **Epic** is held back — an Epic is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, moved out of the ready pickup queue for repair/rollup and never dispatched.
|
|
216
216
|
|
|
217
217
|
**Lifecycle repair (default action for a flagged container).** Move the issue out of the pickup queue by removing `$READY` and adding `$CLAIMED`, post a single lifecycle-repair comment, and record the issue under "Repaired (container)" in the summary. Do NOT invoke `lisa:github-agent`. Keep the comment idempotent — skip posting if an identical `[claude-build-intake]` lifecycle-repair comment already exists on the issue, so a re-entrant cycle doesn't spam it.
|
|
218
218
|
|
|
219
219
|
```bash
|
|
220
220
|
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
221
|
-
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Lifecycle repair: this issue carried the build-ready role ($READY) but is a parent/container with open child work (or a childless Epic
|
|
221
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Lifecycle repair: this issue carried the build-ready role ($READY) but is a parent/container with open child work (or a childless Epic). I moved it to $CLAIMED without invoking the build agent. For parent/container issues, $CLAIMED means rollup/build-lane progress through child/leaf work; direct implementation must happen on leaf issues. Build-ready is leaf-only per leaf-only-lifecycle — move $READY onto its leaf children, or decompose/reclassify a childless Epic."
|
|
222
222
|
```
|
|
223
223
|
|
|
224
224
|
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.
|
|
@@ -326,7 +326,7 @@ Total PRs opened: <n>
|
|
|
326
326
|
|
|
327
327
|
## Idempotency & safety
|
|
328
328
|
|
|
329
|
-
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any leaf claim; a container with open child work (or a childless Epic
|
|
329
|
+
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any leaf claim; a container with open child work (or a childless Epic) is moved `$READY` → `$CLAIMED` as lifecycle repair and never dispatched. The lifecycle-repair comment is idempotent — a re-entrant cycle does not re-post it.
|
|
330
330
|
- **Dependency hold runs before leaf claim**: explicit `Blocked by:` relationships are resolved after container repair is ruled out but before `$READY → $CLAIMED`; active blockers leave the leaf candidate in `$READY` and are reported as skipped, not blocked.
|
|
331
331
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation for leaves; containers are also moved to `$CLAIMED` to leave the ready pickup queue, but are not dispatched.
|
|
332
332
|
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. For containers, `$READY → $CLAIMED` is a lifecycle repair, not a direct build claim. Every other label change is owned by `lisa:github-agent`.
|
|
@@ -351,7 +351,7 @@ If the repo has not adopted the `status:*` label namespace, this skill cannot ru
|
|
|
351
351
|
|
|
352
352
|
## Rules
|
|
353
353
|
|
|
354
|
-
- **Dispatch leaves only.** Per the `leaf-only-lifecycle` rule, never dispatch a container — an issue with open child work, or a childless Epic
|
|
354
|
+
- **Dispatch leaves only.** Per the `leaf-only-lifecycle` rule, never dispatch a container — an issue with open child work, or a childless Epic — even if it carries the build-ready role. Move it `$READY → $CLAIMED` as lifecycle repair (Phase 3a); never silently implement a container.
|
|
355
355
|
- Never relabel an issue outside the cycle's allowed transitions. The `$CLAIMED` label is the signature of cycle ownership for leaves, and the parent/container progress state for lifecycle repairs.
|
|
356
356
|
- Never bypass `lisa:github-agent` to do build work directly. `lisa:github-agent` owns the per-issue lifecycle.
|
|
357
357
|
- Never auto-transition past `$DONE`. Downstream labels (terminal `status:done`, etc.) are owned by QA / PM / merge automation.
|
|
@@ -161,11 +161,11 @@ If the spec doesn't set `authenticated_surface`, infer it: scan the body and AC
|
|
|
161
161
|
|
|
162
162
|
#### S10 — Repository section, single-repo scope
|
|
163
163
|
|
|
164
|
-
When `issue_type ∈ {Bug, Task, Sub-task, Improvement}
|
|
164
|
+
When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` — or a **build-ready childless Story/Spike** (a claimable leaf per `leaf-only-lifecycle`) — body must contain `## Repository` naming exactly one repo. Multiple repos OR cross-repo references in AC: FAIL with recommendation `"Split into per-repo work units under a shared parent Story (see lisa:task-decomposition step 1.5)"`.
|
|
165
165
|
|
|
166
166
|
(GitHub Issues live in one repo by definition, so the `## Repository` section is technically redundant — keep it for parity with the JIRA path so downstream tooling sees the same shape. Cross-repo references in AC are still possible and still fail this gate.)
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
An **Epic**, or a **Story/Spike that still holds child work** (or is not build-ready): skipped (may span repos — coordination containers, not claimable leaf work units).
|
|
169
169
|
|
|
170
170
|
This gate is `product_relevant: false` because cross-repo work units are not a product question — they are a decomposition error. Callers (`lisa:github-to-tracker`, `lisa:notion-to-tracker`, etc.) MUST pre-split cross-repo work into per-repo work units during the decomposition phase per `lisa:task-decomposition` step 1.5; an S10 failure here indicates the agent skipped that step and must auto-split + revalidate before writing, not surface a clarifying comment to product.
|
|
171
171
|
|
|
@@ -199,7 +199,7 @@ When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND `runtime_behavior_c
|
|
|
199
199
|
|
|
200
200
|
FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]` markers, or when any marker name is empty, duplicated, or not kebab-case. A behavior-changing work unit SHOULD declare both a success marker and an error/edge marker; a journey with only one marker passes but the remediation should recommend adding the error/edge case.
|
|
201
201
|
|
|
202
|
-
This gate depends on S11. It is `N/A` for Epic
|
|
202
|
+
This gate depends on S11. It is `N/A` for containers — an **Epic**, or any item with open child work (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:github-add-journey`.
|
|
203
203
|
|
|
204
204
|
#### S15 — Leaf-only build-ready
|
|
205
205
|
|
|
@@ -211,20 +211,19 @@ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only
|
|
|
211
211
|
|
|
212
212
|
Apply this decision and FAIL the two invariant-violating cases:
|
|
213
213
|
|
|
214
|
-
1. **Container with child work + build-ready** —
|
|
215
|
-
2. **Childless
|
|
214
|
+
1. **Container with child work + build-ready** — child work is present (any type that has open children), AND build-ready. FAIL. A parent organizes work; it is never claimed and implemented directly. Its lifecycle state rolls up from its children.
|
|
215
|
+
2. **Childless Epic + build-ready** — `issue_type = Epic` with **no** child work, AND build-ready. Still FAIL: an Epic is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, not an implementable unit. (A childless Story or Spike is **not** failed here — the childless-parent exception in `leaf-only-lifecycle` promotes every childless non-Epic type to a build-ready leaf.)
|
|
216
216
|
|
|
217
|
-
PASS (the childless-parent exception) when the issue is build-ready and is a **leaf work unit**: `issue_type
|
|
217
|
+
PASS (the childless-parent exception) when the issue is build-ready and is a **leaf work unit**: it has **no** open child work and `issue_type ≠ Epic` (i.e. `Bug, Task, Sub-task, Improvement`, or a childless `Story` / `Spike`). A flat Task/Bug, or a childless Story/Spike with no sub-issues, is a valid build-ready leaf and must not be stranded.
|
|
218
218
|
|
|
219
219
|
| issue_type | has child work | build-ready | S15 |
|
|
220
220
|
|---|---|---|---|
|
|
221
|
-
| Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
|
|
222
|
-
|
|
|
223
|
-
| Epic
|
|
224
|
-
| Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
|
|
221
|
+
| Bug / Task / Sub-task / Improvement / Story / Spike | no | yes | **PASS** (leaf) |
|
|
222
|
+
| any type | yes | yes | **FAIL** (structurally a container) |
|
|
223
|
+
| Epic | no | yes | **FAIL** (childless Epic — pure rollup container, exception does not apply) |
|
|
225
224
|
| any | any | no | **N/A** (not build-ready) |
|
|
226
225
|
|
|
227
|
-
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
|
|
226
|
+
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."`
|
|
228
227
|
|
|
229
228
|
`product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
|
|
230
229
|
|
|
@@ -90,7 +90,7 @@ Use verdicts as stable operator language, not as an excuse to dump raw tracker s
|
|
|
90
90
|
- `ELIGIBLE_FOR_REPAIR`: the item is Lisa-owned, stale or stuck enough to qualify for `/lisa:repair-intake`, and repair suppression rules are not currently preventing action.
|
|
91
91
|
- `WAITING_ON_STALENESS`: the item is Lisa-owned but too fresh to repair yet; explain which activity signal or freshness window is still protecting it from a repair loop.
|
|
92
92
|
- `HELD_BY_BLOCKERS`: the item is otherwise actionable, but explicit blockers or dependency holds mean Lisa would wait rather than claim it.
|
|
93
|
-
- `NON_LEAF_CONTAINER`: the item is structurally a container, childless Epic
|
|
93
|
+
- `NON_LEAF_CONTAINER`: the item is structurally a container, childless Epic, or otherwise not directly buildable; explain that direct build pickup is disallowed until decomposition or reclassification happens.
|
|
94
94
|
- `PRODUCT_OWNED_STATE`: the item is currently in a product-owned role or pre-intake lane, so Lisa should not mutate it yet.
|
|
95
95
|
- `MISCONFIGURED`: Lisa could not resolve the item's queue, lifecycle namespace, repo scope, or another required contract signal confidently enough to explain actionability.
|
|
96
96
|
|
|
@@ -137,7 +137,7 @@ Report repair readiness in this order:
|
|
|
137
137
|
|
|
138
138
|
The explanation must stay aligned with existing Lisa rules:
|
|
139
139
|
|
|
140
|
-
- If a build item is a parent/container or a childless Epic
|
|
140
|
+
- If a build item is a parent/container or a childless Epic, explain the leaf-only gate and say direct build pickup is not allowed.
|
|
141
141
|
- If a build item has active blockers, list the blocker refs and explain that intake would hold or skip it until they clear.
|
|
142
142
|
- If a PRD is in a product-owned role such as `draft`, `shipped`, or `verified`, explain why intake or repair will not mutate it.
|
|
143
143
|
- If a claimed, in-review, or blocked item is not yet repairable, explain the relevant staleness or backoff condition at a human-readable level.
|
|
@@ -189,7 +189,7 @@ For GitHub build items, collect these reader signals before choosing a verdict:
|
|
|
189
189
|
Apply gate verdicts in the same order as build intake:
|
|
190
190
|
|
|
191
191
|
1. **Repo-scope gate.** A build item carrying `repo:<other>` and not `repo:<current>` is outside this repo's pickup lane. Return `MISCONFIGURED` when repo scope is absent or contradictory enough that the current repo cannot be determined confidently; otherwise explain the repo-scope mismatch and recommend running intake in the target repo or fixing the `repo:<name>` label. For an unlabeled item whose target repo is obvious from the item body, report the inferred repo signal but stay read-only: execution intake would stamp `repo:<name>`, while intake-explain only says it would do so. A multi-repo leaf is not directly buildable; explain that execution intake would split it per `repo-scope-split`, but this read-only diagnosis does not split.
|
|
192
|
-
2. **Leaf-only gate.** If the item has open child work from native GitHub sub-issues or body parentage, return `NON_LEAF_CONTAINER` and explain that direct build pickup is leaf-only per `leaf-only-lifecycle`. If it has no open children but carries a container
|
|
192
|
+
2. **Leaf-only gate.** If the item has open child work from native GitHub sub-issues or body parentage, return `NON_LEAF_CONTAINER` and explain that direct build pickup is leaf-only per `leaf-only-lifecycle`. If it has no open children but carries `type:Epic`, also return `NON_LEAF_CONTAINER` because a childless Epic is a pure rollup container that still needs decomposition or reclassification. (A childless `type:Story` or `type:Spike` is a valid leaf per `leaf-only-lifecycle` and is NOT a `NON_LEAF_CONTAINER` — it is directly buildable.) The next action for a childless Epic is decomposition, moving `status:ready` to leaf children, or correcting the issue type. Execution build intake would move such a stale ready container out of the pickup queue; this read-only diagnosis must not perform that repair.
|
|
193
193
|
3. **Dependency hold gate.** If a single-repo leaf for the current repo has explicit blockers, read each blocker. Closed blockers are clear. Open blockers are clear only when they carry a cleared build status such as `status:code-review`, `status:on-dev`, `status:on-stg`, `status:done`, or the configured done-equivalent labels. Open blockers with `status:ready`, `status:in-progress`, no cleared status label, or inaccessible state are active. Return `HELD_BY_BLOCKERS`, list the active blocker refs, and make the next action blocker resolution rather than `/lisa:intake`.
|
|
194
194
|
4. **Ready leaf.** A build item in the configured ready role, scoped to the current repo, with no open child work and no active blockers returns `ELIGIBLE_FOR_INTAKE`. The `Why:` line should say it is a single-repo leaf for the current repo and that leaf-only, repo-scope, and dependency gates all pass.
|
|
195
195
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: jira-build-intake
|
|
3
|
-
description: "Symmetric counterpart to notion-prd-intake on the JIRA side. Scans a JIRA project (or JQL filter) for tickets in the configured `ready` status, claims the first eligible ticket by transitioning to the configured `claimed` status, runs the implementation/build flow via jira-agent, transitions to the configured `done` status on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic
|
|
3
|
+
description: "Symmetric counterpart to notion-prd-intake on the JIRA side. Scans a JIRA project (or JQL filter) for tickets in the configured `ready` status, claims the first eligible ticket by transitioning to the configured `claimed` status, runs the implementation/build flow via jira-agent, transitions to the configured `done` status on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic) that still carries a stale build-ready status is skipped or safe-blocked with a lifecycle-repair comment, never claimed. The `ready` status is the human-flipped signal that a TODO ticket is truly ready for development — mirroring how Notion PRDs work product Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
4
4
|
allowed-tools: ["Skill", "Bash"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -159,17 +159,17 @@ Classify and act (first match wins). The issue type comes from the ticket's `iss
|
|
|
159
159
|
| Condition | Class | Action |
|
|
160
160
|
|---|---|---|
|
|
161
161
|
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Skip / safe-block — do NOT claim** |
|
|
162
|
-
| no open children AND type
|
|
163
|
-
| no open children AND type
|
|
162
|
+
| no open children AND type = Epic | **Childless Epic (pure rollup container)** | **Skip / safe-block — do NOT claim** |
|
|
163
|
+
| no open children AND type ≠ Epic (Bug, Task, Sub-task, Improvement, Story, Spike, or no recognized type) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
164
164
|
|
|
165
|
-
The childless-parent exception
|
|
165
|
+
The childless-parent exception promotes every childless type **except Epic** to a claimable leaf: a childless Story is a directly shippable increment and a childless Spike *is* the investigation unit, so neither is stranded. Only a childless **Epic** stays unclaimed — an Epic is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, never an implementable unit.
|
|
166
166
|
|
|
167
167
|
**Safe-block (default action for a flagged container).** Leave the build-ready status in place (don't silently transition it away — that hides the lifecycle error), post a single lifecycle-repair comment, record the ticket under "Skipped (container)" in the summary, and end the cycle. Do NOT transition to `$CLAIMED`. Keep the comment idempotent — skip posting if an identical `[claude-build-intake]` lifecycle-repair comment already exists on the ticket, so a re-entrant cycle doesn't spam it.
|
|
168
168
|
|
|
169
169
|
Post via `lisa:atlassian-access` `operation: comment key: <TICKET> body: "<message>"` with:
|
|
170
170
|
|
|
171
171
|
```text
|
|
172
|
-
[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
|
|
172
|
+
[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.
|
|
173
173
|
```
|
|
174
174
|
|
|
175
175
|
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.
|
|
@@ -242,7 +242,7 @@ Total PRs opened: <n>
|
|
|
242
242
|
|
|
243
243
|
## Idempotency & safety
|
|
244
244
|
|
|
245
|
-
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic
|
|
245
|
+
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic) is skipped/safe-blocked, never claimed (the `leaf-only-lifecycle` rule's claim-time arm). The safe-block comment is idempotent — a re-entrant cycle does not re-post it.
|
|
246
246
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:jira-agent` invocation — no double-pickup.
|
|
247
247
|
- **No writes outside the lifecycle**: this skill only transitions `$READY → $CLAIMED` and `$CLAIMED → $DONE`, then verifies terminal native resolution when `$DONE` is the true terminal state per `leaf-only-lifecycle`. Every other status change is owned by `lisa:jira-agent` (which suggests transitions but only auto-transitions on the verify-FAIL path).
|
|
248
248
|
- **Terminal native closure**: for terminal `$DONE`, the resulting JIRA issue must be in a resolved / closed state (`statusCategory = Done` and resolution set when required). Intermediate env statuses stay unresolved / open.
|
|
@@ -276,7 +276,7 @@ If a ready-equivalent status does not exist in the JIRA project's workflow, this
|
|
|
276
276
|
|
|
277
277
|
## Rules
|
|
278
278
|
|
|
279
|
-
- **Claim leaves only.** Per the `leaf-only-lifecycle` rule, never claim a container — a ticket with open child work, or a childless Epic
|
|
279
|
+
- **Claim leaves only.** Per the `leaf-only-lifecycle` rule, never claim a container — a ticket with open child work, or a childless Epic — even if it carries the build-ready status. Skip or safe-block it (Phase 3a); never silently implement a container.
|
|
280
280
|
- Never transition a ticket the cycle didn't claim. The `$CLAIMED` transition is the signature of cycle ownership.
|
|
281
281
|
- Never bypass `lisa:jira-agent` to do build work directly. `lisa:jira-agent` owns the per-ticket lifecycle (read, verify, triage, route, sync, evidence). This skill is the dispatcher, not the builder.
|
|
282
282
|
- Never auto-transition past `$DONE`. Downstream statuses are owned by QA / product / a future verification-intake skill — not this one.
|
|
@@ -162,9 +162,9 @@ If the spec doesn't set `authenticated_surface`, infer it: scan the description
|
|
|
162
162
|
|
|
163
163
|
#### S10 — Repository section, single-repo scope
|
|
164
164
|
|
|
165
|
-
When `issue_type ∈ {Bug, Task, Sub-task, Improvement}
|
|
165
|
+
When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` — or a **build-ready childless Story/Spike** (a claimable leaf per `leaf-only-lifecycle`) — description must contain `h2. Repository` naming exactly one repo. Multiple repos OR cross-repo references in AC: FAIL with recommendation `"Split into per-repo work units under a shared parent Story (see lisa:task-decomposition step 1.5)"`.
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
An **Epic**, or a **Story/Spike that still holds child work** (or is not build-ready): skipped (may span repos — coordination containers, not claimable leaf work units).
|
|
168
168
|
|
|
169
169
|
This gate is `product_relevant: false` because cross-repo work units are not a product question — they are a decomposition error. Callers (`lisa:notion-to-tracker`, `lisa:confluence-to-tracker`, `lisa:linear-to-tracker`, `lisa:github-to-tracker`) MUST pre-split cross-repo work into per-repo work units during the decomposition phase per `lisa:task-decomposition` step 1.5; an S10 failure here indicates the agent skipped that step and must auto-split + revalidate before writing, not surface a clarifying comment to product.
|
|
170
170
|
|
|
@@ -200,7 +200,7 @@ When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND `runtime_behavior_c
|
|
|
200
200
|
|
|
201
201
|
FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]` markers, or when any marker name is empty, duplicated, or not kebab-case. A behavior-changing work unit SHOULD declare both a success marker and an error/edge marker; a journey with only one marker passes but the remediation should recommend adding the error/edge case.
|
|
202
202
|
|
|
203
|
-
This gate depends on S11. It is `N/A` for Epic
|
|
203
|
+
This gate depends on S11. It is `N/A` for containers — an **Epic**, or any item with open child work (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`.
|
|
204
204
|
|
|
205
205
|
#### S15 — Leaf-only build-ready
|
|
206
206
|
|
|
@@ -212,20 +212,19 @@ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only
|
|
|
212
212
|
|
|
213
213
|
Apply this decision and FAIL the two invariant-violating cases:
|
|
214
214
|
|
|
215
|
-
1. **Container with child work + build-ready** —
|
|
216
|
-
2. **Childless
|
|
215
|
+
1. **Container with child work + build-ready** — child work is present (any type that has open 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 Epic + build-ready** — `issue_type = Epic` with **no** child work, AND build-ready. Still FAIL: an Epic is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, not an implementable unit. (A childless Story or Spike is **not** failed here — the childless-parent exception in `leaf-only-lifecycle` promotes every childless non-Epic type to a build-ready leaf.)
|
|
217
217
|
|
|
218
|
-
PASS (the childless-parent exception) when the ticket is build-ready and is a **leaf work unit**: `issue_type
|
|
218
|
+
PASS (the childless-parent exception) when the ticket is build-ready and is a **leaf work unit**: it has **no** open child work and `issue_type ≠ Epic` (i.e. `Bug, Task, Sub-task, Improvement`, or a childless `Story` / `Spike`). A flat Task/Bug, or a childless Story/Spike with no sub-tasks, is a valid build-ready leaf and must not be stranded.
|
|
219
219
|
|
|
220
220
|
| issue_type | has child work | build-ready | S15 |
|
|
221
221
|
|---|---|---|---|
|
|
222
|
-
| Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
|
|
223
|
-
|
|
|
224
|
-
| Epic
|
|
225
|
-
| Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
|
|
222
|
+
| Bug / Task / Sub-task / Improvement / Story / Spike | no | yes | **PASS** (leaf) |
|
|
223
|
+
| any type | yes | yes | **FAIL** (structurally a container) |
|
|
224
|
+
| Epic | no | yes | **FAIL** (childless Epic — pure rollup container, exception does not apply) |
|
|
226
225
|
| any | any | no | **N/A** (not build-ready) |
|
|
227
226
|
|
|
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
|
|
227
|
+
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."`
|
|
229
228
|
|
|
230
229
|
`product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
|
|
231
230
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: linear-build-intake
|
|
3
|
-
description: "Symmetric counterpart to lisa:jira-build-intake on the Linear side. Scans a Linear team for Issues carrying the configured `ready` build label, claims the first eligible Issue by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:linear-agent, relabels to the configured `done` label on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic
|
|
3
|
+
description: "Symmetric counterpart to lisa:jira-build-intake on the Linear side. Scans a Linear team for Issues carrying the configured `ready` build label, claims the first eligible Issue by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:linear-agent, relabels to the configured `done` label on completion, then exits. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic) that still carries a stale build-ready label is skipped or safe-blocked with a lifecycle-repair comment, never claimed. The `ready` label is the human-flipped signal that an Issue is truly ready for development — mirroring how Notion PRDs work Draft → Ready → (us) In Review → Blocked|Ticketed."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "mcp__linear-server__list_teams", "mcp__linear-server__list_issues", "mcp__linear-server__get_issue", "mcp__linear-server__save_issue", "mcp__linear-server__save_comment", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -167,17 +167,17 @@ Classify and act (first match wins). The type comes from the Issue's `type:` lab
|
|
|
167
167
|
| Condition | Class | Action |
|
|
168
168
|
|---|---|---|
|
|
169
169
|
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Skip / safe-block — do NOT claim** |
|
|
170
|
-
| no open children AND type
|
|
171
|
-
| no open children AND type
|
|
170
|
+
| no open children AND type = Epic (a Linear Project) | **Childless Epic/Project (pure rollup container)** | **Skip / safe-block — do NOT claim** |
|
|
171
|
+
| no open children AND type ≠ Epic (Bug, Task, Sub-task, Improvement, Story, Spike, or no `type:` label) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
172
172
|
|
|
173
|
-
The childless-parent exception
|
|
173
|
+
The childless-parent exception promotes every childless type **except Epic** to a claimable leaf: a childless Story is a directly shippable increment and a childless Spike *is* the investigation unit, so neither is stranded. Only a childless **Epic** (a Linear Project) stays unclaimed — it is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, never an implementable unit.
|
|
174
174
|
|
|
175
175
|
**Safe-block (default action for a flagged container).** Leave the build-ready label in place (don't silently strip it — that hides the lifecycle error), post a single lifecycle-repair comment, record the Issue under "Skipped (container)" in the summary, and end the cycle. Do NOT relabel to `$CLAIMED`. Keep the comment idempotent — skip posting if an identical `[claude-build-intake]` lifecycle-repair comment already exists on the Issue, so a re-entrant cycle doesn't spam it.
|
|
176
176
|
|
|
177
177
|
Post via `mcp__linear-server__save_comment` with:
|
|
178
178
|
|
|
179
179
|
```text
|
|
180
|
-
[claude-build-intake] Not claimed: this Issue carries the build-ready label ($READY) but is a container with open child work (or a childless Epic
|
|
180
|
+
[claude-build-intake] Not claimed: this Issue carries the build-ready label ($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.
|
|
181
181
|
```
|
|
182
182
|
|
|
183
183
|
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 @@ Total PRs opened: <n>
|
|
|
252
252
|
|
|
253
253
|
## Idempotency & safety
|
|
254
254
|
|
|
255
|
-
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic
|
|
255
|
+
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic) is skipped/safe-blocked, never claimed (the `leaf-only-lifecycle` rule's claim-time arm). The safe-block comment is idempotent — a re-entrant cycle does not re-post it.
|
|
256
256
|
- **Claim-first ordering**: `$CLAIMED` set BEFORE agent invocation — no double-pickup.
|
|
257
257
|
- **No writes outside the lifecycle**: this skill only adds/removes `$READY`, `$CLAIMED`, `$DONE`, plus terminal-only native state completion required by `leaf-only-lifecycle`. Every other label change (and non-terminal native state change) is owned by the agent or `lisa:linear-evidence`.
|
|
258
258
|
- **Terminal native closure**: after the `$DONE` label is applied, move the Linear Issue to a native completed state only when `$DONE` is the true terminal done value; intermediate env labels stay open / active.
|
|
@@ -273,7 +273,7 @@ If the team hasn't adopted these labels, the first run exits with an adoption hi
|
|
|
273
273
|
|
|
274
274
|
## Rules
|
|
275
275
|
|
|
276
|
-
- **Claim leaves only.** Per the `leaf-only-lifecycle` rule, never claim a container — an Issue with open child work, or a childless Epic
|
|
276
|
+
- **Claim leaves only.** Per the `leaf-only-lifecycle` rule, never claim a container — an Issue with open child work, or a childless Epic — even if it carries the build-ready label. Skip or safe-block it (Phase 3a); never silently implement a container.
|
|
277
277
|
- Never relabel an Issue the cycle didn't claim. The `$CLAIMED` transition is the signature of cycle ownership.
|
|
278
278
|
- Never bypass `lisa:linear-agent` to do build work directly. The agent owns the per-Issue lifecycle.
|
|
279
279
|
- Never auto-transition past `$DONE`. Downstream labels are owned by QA / product / a future verification-intake skill.
|
|
@@ -165,9 +165,9 @@ If the spec doesn't set `authenticated_surface`, infer it: scan the description
|
|
|
165
165
|
|
|
166
166
|
#### S10 — Repository section, single-repo scope
|
|
167
167
|
|
|
168
|
-
When `issue_type ∈ {Bug, Task, Sub-task, Improvement}
|
|
168
|
+
When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` — or a **build-ready childless Story/Spike** (a claimable leaf per `leaf-only-lifecycle`) — description must contain `## Repository` naming exactly one repo. Multiple repos OR cross-repo references in AC: FAIL with recommendation `"Split into per-repo work units under a shared parent Story (see lisa:task-decomposition step 1.5)"`.
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
An **Epic** (a Linear Project), or a **Story/Spike that still holds child work** (or is not build-ready): skipped (may span repos — coordination containers, not claimable leaf work units).
|
|
171
171
|
|
|
172
172
|
This gate is `product_relevant: false` because cross-repo work units are not a product question — they are a decomposition error. Callers (`lisa:linear-to-tracker`, `lisa:notion-to-tracker`, etc.) MUST pre-split cross-repo work into per-repo work units during the decomposition phase per `lisa:task-decomposition` step 1.5; an S10 failure here indicates the agent skipped that step and must auto-split + revalidate before writing, not surface a clarifying comment to product.
|
|
173
173
|
|
|
@@ -201,7 +201,7 @@ When `issue_type ∈ {Bug, Task, Sub-task, Improvement}` AND `runtime_behavior_c
|
|
|
201
201
|
|
|
202
202
|
FAIL when the Validation Journey is present but declares zero `[EVIDENCE: name]` markers, or when any marker name is empty, duplicated, or not kebab-case. A behavior-changing work unit SHOULD declare both a success marker and an error/edge marker; a journey with only one marker passes but the remediation should recommend adding the error/edge case.
|
|
203
203
|
|
|
204
|
-
This gate depends on S11. It is `N/A` for Project
|
|
204
|
+
This gate depends on S11. It is `N/A` for containers — a **Project** (the Epic equivalent), or any item with open child work (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`.
|
|
205
205
|
|
|
206
206
|
#### S15 — Leaf-only build-ready
|
|
207
207
|
|
|
@@ -213,20 +213,19 @@ Enforces the build-side of the vendor-neutral `leaf-only-lifecycle` rule: **only
|
|
|
213
213
|
|
|
214
214
|
Apply this decision and FAIL the two invariant-violating cases:
|
|
215
215
|
|
|
216
|
-
1. **Container with child work + build-ready** —
|
|
217
|
-
2. **Childless
|
|
216
|
+
1. **Container with child work + build-ready** — child work is present (any type that has open 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 Epic/Project + build-ready** — `issue_type = Epic` (a Linear Project) with **no** child work, AND build-ready. Still FAIL: an Epic/Project is a pure rollup container by design, and a childless one is an incomplete decomposition or a mis-applied role, not an implementable unit. (A childless Story or Spike is **not** failed here — the childless-parent exception in `leaf-only-lifecycle` promotes every childless non-Epic type to a build-ready leaf.)
|
|
218
218
|
|
|
219
|
-
PASS (the childless-parent exception) when the item is build-ready and is a **leaf work unit**: `issue_type
|
|
219
|
+
PASS (the childless-parent exception) when the item is build-ready and is a **leaf work unit**: it has **no** open child work and `issue_type ≠ Epic` (i.e. `Bug, Task, Sub-task, Improvement`, or a childless `Story` / `Spike`). A flat Task/Bug, or a childless Story/Spike with no sub-issues, is a valid build-ready leaf and must not be stranded.
|
|
220
220
|
|
|
221
221
|
| issue_type | has child work | build-ready | S15 |
|
|
222
222
|
|---|---|---|---|
|
|
223
|
-
| Bug / Task / Sub-task / Improvement | no | yes | **PASS** (leaf) |
|
|
224
|
-
|
|
|
225
|
-
| Epic
|
|
226
|
-
| Epic / Story / Spike | no | yes | **FAIL** (childless container-type, exception does not apply) |
|
|
223
|
+
| Bug / Task / Sub-task / Improvement / Story / Spike | no | yes | **PASS** (leaf) |
|
|
224
|
+
| any type | yes | yes | **FAIL** (structurally a container) |
|
|
225
|
+
| Epic (Project) | no | yes | **FAIL** (childless Epic/Project — pure rollup container, exception does not apply) |
|
|
227
226
|
| any | any | no | **N/A** (not build-ready) |
|
|
228
227
|
|
|
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
|
|
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, 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
229
|
|
|
231
230
|
`product_relevant: false` — a build-ready container is a lifecycle/decomposition error for the caller to repair, not a product question.
|
|
232
231
|
|
|
@@ -30,7 +30,7 @@ close-out** roles and moves work *unstuck* or *fully closed*:
|
|
|
30
30
|
out) **and** the *intermediate-env* case (all children shipped to an env like `On Stg`, but the
|
|
31
31
|
parent never advanced — including a parent left stranded in a status it should never carry).
|
|
32
32
|
- **Stale-`ready` container** — a parent/container (open child work, or a childless
|
|
33
|
-
Epic
|
|
33
|
+
**Epic**) wrongly carrying the build-ready role. This is a leaf-only-invariant violation
|
|
34
34
|
the build-intake claim gate deliberately leaves for a human; repair-intake reconciles it by
|
|
35
35
|
rolling the parent up from its children (with an audit note), so a container never sits in `ready`
|
|
36
36
|
indefinitely.
|
|
@@ -364,7 +364,7 @@ native-open / active / unresolved:
|
|
|
364
364
|
|
|
365
365
|
### Build parent rollup reconciliation (intermediate-env or terminal close-out)
|
|
366
366
|
|
|
367
|
-
For each parent/container item (Epic,
|
|
367
|
+
For each parent/container item (an Epic, a Linear Project, or any item — of any type — with open child work),
|
|
368
368
|
reconcile its lifecycle state with the roll-up of its children — **including the intermediate-env
|
|
369
369
|
case**, not only fully-terminal close-out. This is the recovery-side complement to the forward
|
|
370
370
|
rollup the `*-sync --rollup` skills perform; it catches a parent that was never rolled up (or was
|