@codyswann/lisa 2.60.0 → 2.60.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/leaf-only-lifecycle.md +3 -3
- package/plugins/lisa/skills/github-build-intake/SKILL.md +18 -17
- package/plugins/lisa/skills/tracker-build-intake/SKILL.md +3 -3
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-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-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-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-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-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-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/leaf-only-lifecycle.md +3 -3
- package/plugins/src/base/skills/github-build-intake/SKILL.md +18 -17
- package/plugins/src/base/skills/tracker-build-intake/SKILL.md +3 -3
package/package.json
CHANGED
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"lodash": ">=4.18.1"
|
|
83
83
|
},
|
|
84
84
|
"name": "@codyswann/lisa",
|
|
85
|
-
"version": "2.60.
|
|
85
|
+
"version": "2.60.1",
|
|
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": {
|
|
@@ -10,7 +10,7 @@ The first two are the same idea seen from opposite ends: a parent never enters t
|
|
|
10
10
|
|
|
11
11
|
## Why this exists
|
|
12
12
|
|
|
13
|
-
Build intake
|
|
13
|
+
Build intake processes whatever carries the build-ready role (the `ready` role — see `config-resolution`). A parent container (an Epic, a Story, a Linear Project, any issue with child work) is not a unit of implementation; it organizes work. If a parent is marked build-ready, an agent may try to implement the container itself unless intake gates it first — the wrong permission and lifecycle boundary. This surfaced in real PRD intake: a PRD decomposed into an Epic, Stories, and Sub-tasks, and *every* item received the build-ready label, so a subsequent build pass would have tried to "implement" the Epic.
|
|
14
14
|
|
|
15
15
|
The fix is not vendor-specific. It belongs here, in a cross-vendor rule, and every writer / validator / intake path enforces it.
|
|
16
16
|
|
|
@@ -43,7 +43,7 @@ Where a vendor lacks native hierarchy for a given pair, a text link or metadata
|
|
|
43
43
|
|
|
44
44
|
- **At decomposition / write time** — when a PRD decomposes into a hierarchy, only the leaf work units receive the `ready` role (status/label). Parent containers (Epic, Story, Project, and any parent issue that has child work) are created in their normal non-ready state and never receive the build-ready role directly. The leaves are what downstream build intake will claim.
|
|
45
45
|
- **At validate time** — the `*-validate-*` gate FAILs any container carrying the build-ready role. This is the symmetric write-side guard: a stale or hand-applied build-ready role on a parent is a lifecycle error.
|
|
46
|
-
- **At claim time** — build intake scans for the `ready` role but
|
|
46
|
+
- **At claim time** — build intake scans for the `ready` role but dispatches **only leaf work units**. A container that still carries a stale build-ready role (e.g. applied before this rule existed) is **not dispatched**: intake either moves it into the vendor's parent/container progress state or safely blocks it with a clear lifecycle-repair message. Intake never silently implements a container.
|
|
47
47
|
|
|
48
48
|
The permission boundary is the maintainer-applied build-ready role, not authorship — do not add author-based guards (PRD #522 non-goal). This rule narrows *what* may carry that role, not *who* may apply it.
|
|
49
49
|
|
|
@@ -108,7 +108,7 @@ Skills that enforce this invariant or perform rollup cite this rule by slug (the
|
|
|
108
108
|
|
|
109
109
|
- **Decomposition / write** (`*-to-tracker`, `*-write-*`) — apply the `ready` role to leaves only; never to containers.
|
|
110
110
|
- **Validate** (`*-validate-*`) — FAIL a container carrying the build-ready role; FAIL a childless Epic/Story/Spike marked build-ready.
|
|
111
|
-
- **Build intake** (`*-build-intake`, `tracker-build-intake`) —
|
|
111
|
+
- **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.
|
|
112
112
|
- **Rollup** — derive parent state from children per the state machine above.
|
|
113
113
|
- **Terminal native closure** (`*-build-intake`, terminal helpers) — after a leaf reaches the true terminal `done` role, finalize it through the provider's native close / complete / resolve mechanism where available; never do this for intermediate env states.
|
|
114
114
|
|
|
@@ -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, claims each leaf work unit by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:github-agent, and relabels to the configured `done` label on completion. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic/Story/Spike) that still carries a stale build-ready label is
|
|
3
|
+
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, claims each leaf work unit by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:github-agent, and relabels to the configured `done` label on completion. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic/Story/Spike) 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
|
|
|
@@ -135,11 +135,11 @@ If none of the configured role labels exist on the repo → label convention not
|
|
|
135
135
|
|
|
136
136
|
### Phase 3 — Process each ready issue (serial)
|
|
137
137
|
|
|
138
|
-
#### 3a. Leaf-only claim gate (
|
|
138
|
+
#### 3a. Leaf-only claim gate (repair containers)
|
|
139
139
|
|
|
140
|
-
Build intake
|
|
140
|
+
Build intake dispatches **only independently implementable leaf work units** to the build agent. This enforces the claim-time arm of the vendor-neutral `leaf-only-lifecycle` rule: a parent/container that still carries a stale build-ready role (e.g. `status:ready` applied before this rule existed, or hand-applied to an Epic/Story) is **never dispatched** — intake moves it out of the pickup queue by replacing `$READY` with `$CLAIMED`, then posts a clear lifecycle-repair message. It is the claim-time complement to the write-time labeling in `lisa:github-write-issue` and the validate-time S15 gate in `lisa:github-validate-issue`; all three cite the same rule so the classification never drifts. **Never silently implement a container.**
|
|
141
141
|
|
|
142
|
-
Run this gate **before** the claim relabel, for every candidate issue. Do NOT
|
|
142
|
+
Run this gate **before** the leaf claim relabel, for every candidate issue. Do NOT comment "Claimed" or invoke `lisa:github-agent` for an issue that fails the gate. A container repair still changes labels: remove `$READY`, add `$CLAIMED`, and explain that parent/container `$CLAIMED` means rollup/build-lane progress through child/leaf work, not direct implementation.
|
|
143
143
|
|
|
144
144
|
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `Parent: #<n>` references). Dependency links such as `Blocked by:` are not parentage; they are handled by the active dependency hold gate below.
|
|
145
145
|
|
|
@@ -168,16 +168,17 @@ Classify and act (first match wins). `type:` is read from the issue's labels (`t
|
|
|
168
168
|
|
|
169
169
|
| Condition | Class | Action |
|
|
170
170
|
|---|---|---|
|
|
171
|
-
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **
|
|
172
|
-
| no open children AND `type ∈ {Epic, Story, Spike}` | **Childless container-type** | **
|
|
171
|
+
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
172
|
+
| no open children AND `type ∈ {Epic, Story, Spike}` | **Childless container-type** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
173
173
|
| no open children AND `type ∈ {Bug, Task, Sub-task, Improvement}` (or no `type:` label) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
174
174
|
|
|
175
|
-
The childless-parent exception is narrow: childlessness enables
|
|
175
|
+
The childless-parent exception is narrow: childlessness enables direct build-agent dispatch **only** for types that are leaf work units to begin with. A childless Epic/Story/Spike is an incomplete decomposition, not an implementable unit — it is moved out of the ready pickup queue for repair/rollup and never dispatched.
|
|
176
176
|
|
|
177
|
-
**
|
|
177
|
+
**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.
|
|
178
178
|
|
|
179
179
|
```bash
|
|
180
|
-
gh issue
|
|
180
|
+
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
181
|
+
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/Story/Spike). 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/Story/Spike."
|
|
181
182
|
```
|
|
182
183
|
|
|
183
184
|
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.
|
|
@@ -269,8 +270,8 @@ Cycle completed: <ISO timestamp>
|
|
|
269
270
|
Issues processed: <n>
|
|
270
271
|
- $DONE (build complete, PR ready): <n>
|
|
271
272
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
272
|
-
-
|
|
273
|
-
- <org>/<repo>#<number> <title> — build-ready on a parent
|
|
273
|
+
- Repaired (container — leaf-only-lifecycle): <n>
|
|
274
|
+
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without invoking lisa:github-agent; lifecycle-repair comment posted
|
|
274
275
|
- Skipped (active blockers): <n>
|
|
275
276
|
- <org>/<repo>#<number> <title> — waiting on <blocker refs>
|
|
276
277
|
- Blocked (pre-flight verify failed): <n>
|
|
@@ -285,10 +286,10 @@ Total PRs opened: <n>
|
|
|
285
286
|
|
|
286
287
|
## Idempotency & safety
|
|
287
288
|
|
|
288
|
-
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic/Story/Spike) is
|
|
289
|
-
- **Dependency hold runs before claim**: explicit `Blocked by:` relationships are resolved before `$READY → $CLAIMED`; active blockers leave the candidate in `$READY` and are reported as skipped, not blocked.
|
|
290
|
-
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation
|
|
291
|
-
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. Every other label change is owned by `lisa:github-agent`.
|
|
289
|
+
- **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/Story/Spike) 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.
|
|
290
|
+
- **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.
|
|
291
|
+
- **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.
|
|
292
|
+
- **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`.
|
|
292
293
|
- **Terminal native closure**: after `$CLAIMED → $DONE`, close the GitHub issue only when `$DONE` is the true terminal done value per `leaf-only-lifecycle`; intermediate env labels stay open.
|
|
293
294
|
- **Failure isolation**: per-issue exceptions caught and recorded; the cycle continues.
|
|
294
295
|
- **Single cycle per repo**: do not run two `lisa:github-build-intake` cycles in parallel against the same repo — concurrent claims could race. The scheduling layer is responsible for serialization.
|
|
@@ -311,8 +312,8 @@ If the repo has not adopted the `status:*` label namespace, this skill cannot ru
|
|
|
311
312
|
|
|
312
313
|
## Rules
|
|
313
314
|
|
|
314
|
-
- **
|
|
315
|
-
- Never relabel an issue the cycle
|
|
315
|
+
- **Dispatch leaves only.** Per the `leaf-only-lifecycle` rule, never dispatch a container — an issue with open child work, or a childless Epic/Story/Spike — even if it carries the build-ready role. Move it `$READY → $CLAIMED` as lifecycle repair (Phase 3a); never silently implement a container.
|
|
316
|
+
- 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.
|
|
316
317
|
- Never bypass `lisa:github-agent` to do build work directly. `lisa:github-agent` owns the per-issue lifecycle.
|
|
317
318
|
- Never auto-transition past `$DONE`. Downstream labels (terminal `status:done`, etc.) are owned by QA / PM / merge automation.
|
|
318
319
|
- Never close a GitHub issue at intermediate env states (`status:on-dev`, `status:on-stg`, or configured equivalents). Native close happens only at the terminal `done` value.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tracker-build-intake
|
|
3
|
-
description: "Vendor-neutral wrapper for the build-queue batch scanner. Reads `tracker` from .lisa.config.json (default: jira) and dispatches to lisa:jira-build-intake (JQL/project-key queue), lisa:github-build-intake (GitHub repo queue keyed off the `status:ready` label), or lisa:linear-build-intake (Linear team queue keyed off the `status:ready` label). Every vendor scanner enforces the claim-time arm of the `leaf-only-lifecycle` rule —
|
|
3
|
+
description: "Vendor-neutral wrapper for the build-queue batch scanner. Reads `tracker` from .lisa.config.json (default: jira) and dispatches to lisa:jira-build-intake (JQL/project-key queue), lisa:github-build-intake (GitHub repo queue keyed off the `status:ready` label), or lisa:linear-build-intake (Linear team queue keyed off the `status:ready` label). Every vendor scanner enforces the claim-time arm of the `leaf-only-lifecycle` rule — dispatch leaf work units only; move or safe-block a container with open child work (or a childless Epic/Story/Spike) that carries a stale build-ready role according to the vendor's lifecycle semantics. Counterpart to lisa:intake's PRD-side dispatchers."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "Read"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -27,7 +27,7 @@ The vendor scanners also own the terminal native-closure step from `leaf-only-li
|
|
|
27
27
|
This shim is dispatch only — it does not reclassify or re-gate items — but the contract it forwards is part of the build-intake API, so it is documented here once and the three vendor scanners implement it identically. Per the vendor-neutral `leaf-only-lifecycle` rule, **build intake claims only independently implementable leaf work units**:
|
|
28
28
|
|
|
29
29
|
- A **leaf work unit** (Bug, Task, Sub-task, Improvement with no open child work) is claimed and built.
|
|
30
|
-
- A **container** — anything with open child work, or a childless Epic/Story/Spike — that still carries a stale build-ready role is **never
|
|
30
|
+
- A **container** — anything with open child work, or a childless Epic/Story/Spike — that still carries a stale build-ready role is **never dispatched**. The GitHub scanner moves it out of the pickup queue by replacing `status:ready` with `status:in-progress` and posting an idempotent lifecycle-repair comment; other vendor scanners skip or safe-block according to their native lifecycle semantics.
|
|
31
31
|
|
|
32
32
|
This is the claim-time arm of the rule. Its siblings are the write-time labeling (`lisa:tracker-write` → the vendor `*-write-*` skills apply build-ready to leaves only) and the validate-time S15 gate (`lisa:tracker-validate` → the vendor `*-validate-*` skills FAIL a build-ready container). All three arms cite `leaf-only-lifecycle` so no vendor drifts. Each vendor scanner implements the gate against its own hierarchy:
|
|
33
33
|
|
|
@@ -55,6 +55,6 @@ Intermediate env states are not native closure. A vendor scanner that resolves `
|
|
|
55
55
|
|
|
56
56
|
- Single cycle per invocation — the vendor skill processes the current `Ready` set and exits.
|
|
57
57
|
- The vendor skills run their own pre-flight checks (JIRA workflow transitions for the JIRA path; label namespace adoption for the GitHub and Linear paths) before processing items. Never bypass.
|
|
58
|
-
- **Leaf-only
|
|
58
|
+
- **Leaf-only dispatch, every vendor.** Per the `leaf-only-lifecycle` rule, each vendor scanner dispatches leaf work units only and moves or safe-blocks a container (open child work, or a childless Epic/Story/Spike) carrying a stale build-ready role according to its lifecycle semantics. This shim does not re-implement the gate — it relies on the vendor scanner's Phase 3a — but the contract is uniform across `jira`, `github`, and `linear` so behavior never drifts by tracker.
|
|
59
59
|
- **Terminal native closure, every capable vendor.** Per the same rule, each vendor scanner finalizes native open/closed state only at the true terminal `done` value. This shim never performs native closure itself, but callers can rely on the dispatched vendor scanner to apply the contract.
|
|
60
60
|
- Never run two intake cycles concurrently against overlapping queues — the scheduling layer is responsible for serialization.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "2.60.
|
|
3
|
+
"version": "2.60.1",
|
|
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.60.
|
|
3
|
+
"version": "2.60.1",
|
|
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"
|
|
@@ -10,7 +10,7 @@ The first two are the same idea seen from opposite ends: a parent never enters t
|
|
|
10
10
|
|
|
11
11
|
## Why this exists
|
|
12
12
|
|
|
13
|
-
Build intake
|
|
13
|
+
Build intake processes whatever carries the build-ready role (the `ready` role — see `config-resolution`). A parent container (an Epic, a Story, a Linear Project, any issue with child work) is not a unit of implementation; it organizes work. If a parent is marked build-ready, an agent may try to implement the container itself unless intake gates it first — the wrong permission and lifecycle boundary. This surfaced in real PRD intake: a PRD decomposed into an Epic, Stories, and Sub-tasks, and *every* item received the build-ready label, so a subsequent build pass would have tried to "implement" the Epic.
|
|
14
14
|
|
|
15
15
|
The fix is not vendor-specific. It belongs here, in a cross-vendor rule, and every writer / validator / intake path enforces it.
|
|
16
16
|
|
|
@@ -43,7 +43,7 @@ Where a vendor lacks native hierarchy for a given pair, a text link or metadata
|
|
|
43
43
|
|
|
44
44
|
- **At decomposition / write time** — when a PRD decomposes into a hierarchy, only the leaf work units receive the `ready` role (status/label). Parent containers (Epic, Story, Project, and any parent issue that has child work) are created in their normal non-ready state and never receive the build-ready role directly. The leaves are what downstream build intake will claim.
|
|
45
45
|
- **At validate time** — the `*-validate-*` gate FAILs any container carrying the build-ready role. This is the symmetric write-side guard: a stale or hand-applied build-ready role on a parent is a lifecycle error.
|
|
46
|
-
- **At claim time** — build intake scans for the `ready` role but
|
|
46
|
+
- **At claim time** — build intake scans for the `ready` role but dispatches **only leaf work units**. A container that still carries a stale build-ready role (e.g. applied before this rule existed) is **not dispatched**: intake either moves it into the vendor's parent/container progress state or safely blocks it with a clear lifecycle-repair message. Intake never silently implements a container.
|
|
47
47
|
|
|
48
48
|
The permission boundary is the maintainer-applied build-ready role, not authorship — do not add author-based guards (PRD #522 non-goal). This rule narrows *what* may carry that role, not *who* may apply it.
|
|
49
49
|
|
|
@@ -108,7 +108,7 @@ Skills that enforce this invariant or perform rollup cite this rule by slug (the
|
|
|
108
108
|
|
|
109
109
|
- **Decomposition / write** (`*-to-tracker`, `*-write-*`) — apply the `ready` role to leaves only; never to containers.
|
|
110
110
|
- **Validate** (`*-validate-*`) — FAIL a container carrying the build-ready role; FAIL a childless Epic/Story/Spike marked build-ready.
|
|
111
|
-
- **Build intake** (`*-build-intake`, `tracker-build-intake`) —
|
|
111
|
+
- **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.
|
|
112
112
|
- **Rollup** — derive parent state from children per the state machine above.
|
|
113
113
|
- **Terminal native closure** (`*-build-intake`, terminal helpers) — after a leaf reaches the true terminal `done` role, finalize it through the provider's native close / complete / resolve mechanism where available; never do this for intermediate env states.
|
|
114
114
|
|
|
@@ -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, claims each leaf work unit by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:github-agent, and relabels to the configured `done` label on completion. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic/Story/Spike) that still carries a stale build-ready label is
|
|
3
|
+
description: "GitHub counterpart to lisa:jira-build-intake. Scans a GitHub repository for issues carrying the configured `ready` build label, claims each leaf work unit by relabeling to the configured `claimed` label, runs the implementation/build flow via lisa:github-agent, and relabels to the configured `done` label on completion. Enforces the claim-time arm of the `leaf-only-lifecycle` rule: a parent/container with open child work (or a childless Epic/Story/Spike) 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
|
|
|
@@ -135,11 +135,11 @@ If none of the configured role labels exist on the repo → label convention not
|
|
|
135
135
|
|
|
136
136
|
### Phase 3 — Process each ready issue (serial)
|
|
137
137
|
|
|
138
|
-
#### 3a. Leaf-only claim gate (
|
|
138
|
+
#### 3a. Leaf-only claim gate (repair containers)
|
|
139
139
|
|
|
140
|
-
Build intake
|
|
140
|
+
Build intake dispatches **only independently implementable leaf work units** to the build agent. This enforces the claim-time arm of the vendor-neutral `leaf-only-lifecycle` rule: a parent/container that still carries a stale build-ready role (e.g. `status:ready` applied before this rule existed, or hand-applied to an Epic/Story) is **never dispatched** — intake moves it out of the pickup queue by replacing `$READY` with `$CLAIMED`, then posts a clear lifecycle-repair message. It is the claim-time complement to the write-time labeling in `lisa:github-write-issue` and the validate-time S15 gate in `lisa:github-validate-issue`; all three cite the same rule so the classification never drifts. **Never silently implement a container.**
|
|
141
141
|
|
|
142
|
-
Run this gate **before** the claim relabel, for every candidate issue. Do NOT
|
|
142
|
+
Run this gate **before** the leaf claim relabel, for every candidate issue. Do NOT comment "Claimed" or invoke `lisa:github-agent` for an issue that fails the gate. A container repair still changes labels: remove `$READY`, add `$CLAIMED`, and explain that parent/container `$CLAIMED` means rollup/build-lane progress through child/leaf work, not direct implementation.
|
|
143
143
|
|
|
144
144
|
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: an issue is a **container** if it has **open** child work, whatever its declared type; otherwise the **type label** decides. Resolve child work using the same hierarchy `lisa:github-read-issue` uses — native sub-issues first, then body parentage (task-list checkboxes referencing other issues, `Parent: #<n>` references). Dependency links such as `Blocked by:` are not parentage; they are handled by the active dependency hold gate below.
|
|
145
145
|
|
|
@@ -168,16 +168,17 @@ Classify and act (first match wins). `type:` is read from the issue's labels (`t
|
|
|
168
168
|
|
|
169
169
|
| Condition | Class | Action |
|
|
170
170
|
|---|---|---|
|
|
171
|
-
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **
|
|
172
|
-
| no open children AND `type ∈ {Epic, Story, Spike}` | **Childless container-type** | **
|
|
171
|
+
| `OPEN_CHILDREN > 0` (open child work, any type) | **Container** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
172
|
+
| no open children AND `type ∈ {Epic, Story, Spike}` | **Childless container-type** | **Move to `$CLAIMED` as lifecycle repair — do NOT dispatch** |
|
|
173
173
|
| no open children AND `type ∈ {Bug, Task, Sub-task, Improvement}` (or no `type:` label) | **Leaf work unit** | **Proceed to 3b claim** |
|
|
174
174
|
|
|
175
|
-
The childless-parent exception is narrow: childlessness enables
|
|
175
|
+
The childless-parent exception is narrow: childlessness enables direct build-agent dispatch **only** for types that are leaf work units to begin with. A childless Epic/Story/Spike is an incomplete decomposition, not an implementable unit — it is moved out of the ready pickup queue for repair/rollup and never dispatched.
|
|
176
176
|
|
|
177
|
-
**
|
|
177
|
+
**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.
|
|
178
178
|
|
|
179
179
|
```bash
|
|
180
|
-
gh issue
|
|
180
|
+
gh issue edit <number> --repo <org>/<repo> --remove-label "$READY" --add-label "$CLAIMED"
|
|
181
|
+
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/Story/Spike). 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/Story/Spike."
|
|
181
182
|
```
|
|
182
183
|
|
|
183
184
|
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.
|
|
@@ -269,8 +270,8 @@ Cycle completed: <ISO timestamp>
|
|
|
269
270
|
Issues processed: <n>
|
|
270
271
|
- $DONE (build complete, PR ready): <n>
|
|
271
272
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
272
|
-
-
|
|
273
|
-
- <org>/<repo>#<number> <title> — build-ready on a parent
|
|
273
|
+
- Repaired (container — leaf-only-lifecycle): <n>
|
|
274
|
+
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without invoking lisa:github-agent; lifecycle-repair comment posted
|
|
274
275
|
- Skipped (active blockers): <n>
|
|
275
276
|
- <org>/<repo>#<number> <title> — waiting on <blocker refs>
|
|
276
277
|
- Blocked (pre-flight verify failed): <n>
|
|
@@ -285,10 +286,10 @@ Total PRs opened: <n>
|
|
|
285
286
|
|
|
286
287
|
## Idempotency & safety
|
|
287
288
|
|
|
288
|
-
- **Leaf-only claim gate runs first**: Phase 3a classifies each candidate before any claim; a container with open child work (or a childless Epic/Story/Spike) is
|
|
289
|
-
- **Dependency hold runs before claim**: explicit `Blocked by:` relationships are resolved before `$READY → $CLAIMED`; active blockers leave the candidate in `$READY` and are reported as skipped, not blocked.
|
|
290
|
-
- **Claim-first ordering**: `$CLAIMED` set BEFORE `lisa:github-agent` invocation
|
|
291
|
-
- **No writes outside the lifecycle**: this skill only relabels `$READY → $CLAIMED` and `$CLAIMED → $DONE`. Every other label change is owned by `lisa:github-agent`.
|
|
289
|
+
- **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/Story/Spike) 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.
|
|
290
|
+
- **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.
|
|
291
|
+
- **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.
|
|
292
|
+
- **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`.
|
|
292
293
|
- **Terminal native closure**: after `$CLAIMED → $DONE`, close the GitHub issue only when `$DONE` is the true terminal done value per `leaf-only-lifecycle`; intermediate env labels stay open.
|
|
293
294
|
- **Failure isolation**: per-issue exceptions caught and recorded; the cycle continues.
|
|
294
295
|
- **Single cycle per repo**: do not run two `lisa:github-build-intake` cycles in parallel against the same repo — concurrent claims could race. The scheduling layer is responsible for serialization.
|
|
@@ -311,8 +312,8 @@ If the repo has not adopted the `status:*` label namespace, this skill cannot ru
|
|
|
311
312
|
|
|
312
313
|
## Rules
|
|
313
314
|
|
|
314
|
-
- **
|
|
315
|
-
- Never relabel an issue the cycle
|
|
315
|
+
- **Dispatch leaves only.** Per the `leaf-only-lifecycle` rule, never dispatch a container — an issue with open child work, or a childless Epic/Story/Spike — even if it carries the build-ready role. Move it `$READY → $CLAIMED` as lifecycle repair (Phase 3a); never silently implement a container.
|
|
316
|
+
- 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.
|
|
316
317
|
- Never bypass `lisa:github-agent` to do build work directly. `lisa:github-agent` owns the per-issue lifecycle.
|
|
317
318
|
- Never auto-transition past `$DONE`. Downstream labels (terminal `status:done`, etc.) are owned by QA / PM / merge automation.
|
|
318
319
|
- Never close a GitHub issue at intermediate env states (`status:on-dev`, `status:on-stg`, or configured equivalents). Native close happens only at the terminal `done` value.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tracker-build-intake
|
|
3
|
-
description: "Vendor-neutral wrapper for the build-queue batch scanner. Reads `tracker` from .lisa.config.json (default: jira) and dispatches to lisa:jira-build-intake (JQL/project-key queue), lisa:github-build-intake (GitHub repo queue keyed off the `status:ready` label), or lisa:linear-build-intake (Linear team queue keyed off the `status:ready` label). Every vendor scanner enforces the claim-time arm of the `leaf-only-lifecycle` rule —
|
|
3
|
+
description: "Vendor-neutral wrapper for the build-queue batch scanner. Reads `tracker` from .lisa.config.json (default: jira) and dispatches to lisa:jira-build-intake (JQL/project-key queue), lisa:github-build-intake (GitHub repo queue keyed off the `status:ready` label), or lisa:linear-build-intake (Linear team queue keyed off the `status:ready` label). Every vendor scanner enforces the claim-time arm of the `leaf-only-lifecycle` rule — dispatch leaf work units only; move or safe-block a container with open child work (or a childless Epic/Story/Spike) that carries a stale build-ready role according to the vendor's lifecycle semantics. Counterpart to lisa:intake's PRD-side dispatchers."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "Read"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -27,7 +27,7 @@ The vendor scanners also own the terminal native-closure step from `leaf-only-li
|
|
|
27
27
|
This shim is dispatch only — it does not reclassify or re-gate items — but the contract it forwards is part of the build-intake API, so it is documented here once and the three vendor scanners implement it identically. Per the vendor-neutral `leaf-only-lifecycle` rule, **build intake claims only independently implementable leaf work units**:
|
|
28
28
|
|
|
29
29
|
- A **leaf work unit** (Bug, Task, Sub-task, Improvement with no open child work) is claimed and built.
|
|
30
|
-
- A **container** — anything with open child work, or a childless Epic/Story/Spike — that still carries a stale build-ready role is **never
|
|
30
|
+
- A **container** — anything with open child work, or a childless Epic/Story/Spike — that still carries a stale build-ready role is **never dispatched**. The GitHub scanner moves it out of the pickup queue by replacing `status:ready` with `status:in-progress` and posting an idempotent lifecycle-repair comment; other vendor scanners skip or safe-block according to their native lifecycle semantics.
|
|
31
31
|
|
|
32
32
|
This is the claim-time arm of the rule. Its siblings are the write-time labeling (`lisa:tracker-write` → the vendor `*-write-*` skills apply build-ready to leaves only) and the validate-time S15 gate (`lisa:tracker-validate` → the vendor `*-validate-*` skills FAIL a build-ready container). All three arms cite `leaf-only-lifecycle` so no vendor drifts. Each vendor scanner implements the gate against its own hierarchy:
|
|
33
33
|
|
|
@@ -55,6 +55,6 @@ Intermediate env states are not native closure. A vendor scanner that resolves `
|
|
|
55
55
|
|
|
56
56
|
- Single cycle per invocation — the vendor skill processes the current `Ready` set and exits.
|
|
57
57
|
- The vendor skills run their own pre-flight checks (JIRA workflow transitions for the JIRA path; label namespace adoption for the GitHub and Linear paths) before processing items. Never bypass.
|
|
58
|
-
- **Leaf-only
|
|
58
|
+
- **Leaf-only dispatch, every vendor.** Per the `leaf-only-lifecycle` rule, each vendor scanner dispatches leaf work units only and moves or safe-blocks a container (open child work, or a childless Epic/Story/Spike) carrying a stale build-ready role according to its lifecycle semantics. This shim does not re-implement the gate — it relies on the vendor scanner's Phase 3a — but the contract is uniform across `jira`, `github`, and `linear` so behavior never drifts by tracker.
|
|
59
59
|
- **Terminal native closure, every capable vendor.** Per the same rule, each vendor scanner finalizes native open/closed state only at the true terminal `done` value. This shim never performs native closure itself, but callers can rely on the dispatched vendor scanner to apply the contract.
|
|
60
60
|
- Never run two intake cycles concurrently against overlapping queues — the scheduling layer is responsible for serialization.
|