@codyswann/lisa 2.198.0 → 2.198.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/.codex-plugin/skills/lisa-debrief/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-build-intake/SKILL.md +30 -34
- package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +6 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-intake/SKILL.md +10 -16
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-build-intake/SKILL.md +28 -32
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-build-intake/SKILL.md +28 -32
- package/plugins/lisa/.codex-plugin/skills/lisa-monitor/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-plan/SKILL.md +6 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +13 -42
- package/plugins/lisa/.codex-plugin/skills/lisa-research/SKILL.md +3 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-verify/SKILL.md +3 -1
- package/plugins/lisa/agents/github-agent.md +3 -1
- package/plugins/lisa/agents/github-build-intake.md +2 -2
- package/plugins/lisa/agents/jira-agent.md +3 -1
- package/plugins/lisa/agents/jira-build-intake.md +2 -2
- package/plugins/lisa/agents/linear-agent.md +3 -1
- package/plugins/lisa/agents/linear-build-intake.md +2 -2
- package/plugins/lisa/rules/eager/intent-routing.md +2 -2
- package/plugins/lisa/rules/reference/intent-routing.md +4 -4
- package/plugins/lisa/skills/lisa-debrief/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-github-build-intake/SKILL.md +31 -35
- package/plugins/lisa/skills/lisa-implement/SKILL.md +6 -2
- package/plugins/lisa/skills/lisa-intake/SKILL.md +10 -16
- package/plugins/lisa/skills/lisa-jira-build-intake/SKILL.md +29 -33
- package/plugins/lisa/skills/lisa-linear-build-intake/SKILL.md +29 -33
- package/plugins/lisa/skills/lisa-monitor/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-plan/SKILL.md +6 -2
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +13 -42
- package/plugins/lisa/skills/lisa-research/SKILL.md +3 -1
- package/plugins/lisa/skills/lisa-verify/SKILL.md +3 -1
- package/plugins/lisa-agy/agents/github-agent.md +3 -1
- package/plugins/lisa-agy/agents/github-build-intake.md +2 -2
- package/plugins/lisa-agy/agents/jira-agent.md +3 -1
- package/plugins/lisa-agy/agents/jira-build-intake.md +2 -2
- package/plugins/lisa-agy/agents/linear-agent.md +3 -1
- package/plugins/lisa-agy/agents/linear-build-intake.md +2 -2
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-debrief/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-github-build-intake/SKILL.md +31 -35
- package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +6 -2
- package/plugins/lisa-agy/skills/lisa-intake/SKILL.md +10 -16
- package/plugins/lisa-agy/skills/lisa-jira-build-intake/SKILL.md +29 -33
- package/plugins/lisa-agy/skills/lisa-linear-build-intake/SKILL.md +29 -33
- package/plugins/lisa-agy/skills/lisa-monitor/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-plan/SKILL.md +6 -2
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +13 -42
- package/plugins/lisa-agy/skills/lisa-research/SKILL.md +3 -1
- package/plugins/lisa-agy/skills/lisa-verify/SKILL.md +3 -1
- 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/agents/github-agent.agent.md +3 -1
- package/plugins/lisa-copilot/agents/github-build-intake.agent.md +2 -2
- package/plugins/lisa-copilot/agents/jira-agent.agent.md +3 -1
- package/plugins/lisa-copilot/agents/jira-build-intake.agent.md +2 -2
- package/plugins/lisa-copilot/agents/linear-agent.agent.md +3 -1
- package/plugins/lisa-copilot/agents/linear-build-intake.agent.md +2 -2
- package/plugins/lisa-copilot/rules/eager/intent-routing.md +2 -2
- package/plugins/lisa-copilot/rules/reference/intent-routing.md +4 -4
- package/plugins/lisa-copilot/skills/lisa-debrief/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-github-build-intake/SKILL.md +31 -35
- package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +6 -2
- package/plugins/lisa-copilot/skills/lisa-intake/SKILL.md +10 -16
- package/plugins/lisa-copilot/skills/lisa-jira-build-intake/SKILL.md +29 -33
- package/plugins/lisa-copilot/skills/lisa-linear-build-intake/SKILL.md +29 -33
- package/plugins/lisa-copilot/skills/lisa-monitor/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-plan/SKILL.md +6 -2
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +13 -42
- package/plugins/lisa-copilot/skills/lisa-research/SKILL.md +3 -1
- package/plugins/lisa-copilot/skills/lisa-verify/SKILL.md +3 -1
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/agents/github-agent.md +3 -1
- package/plugins/lisa-cursor/agents/github-build-intake.md +2 -2
- package/plugins/lisa-cursor/agents/jira-agent.md +3 -1
- package/plugins/lisa-cursor/agents/jira-build-intake.md +2 -2
- package/plugins/lisa-cursor/agents/linear-agent.md +3 -1
- package/plugins/lisa-cursor/agents/linear-build-intake.md +2 -2
- package/plugins/lisa-cursor/rules/intent-routing-reference.mdc +4 -4
- package/plugins/lisa-cursor/rules/intent-routing.mdc +2 -2
- package/plugins/lisa-cursor/skills/lisa-debrief/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-github-build-intake/SKILL.md +31 -35
- package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +6 -2
- package/plugins/lisa-cursor/skills/lisa-intake/SKILL.md +10 -16
- package/plugins/lisa-cursor/skills/lisa-jira-build-intake/SKILL.md +29 -33
- package/plugins/lisa-cursor/skills/lisa-linear-build-intake/SKILL.md +29 -33
- package/plugins/lisa-cursor/skills/lisa-monitor/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-plan/SKILL.md +6 -2
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +13 -42
- package/plugins/lisa-cursor/skills/lisa-research/SKILL.md +3 -1
- package/plugins/lisa-cursor/skills/lisa-verify/SKILL.md +3 -1
- 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-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-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/agents/github-agent.md +3 -1
- package/plugins/src/base/agents/github-build-intake.md +2 -2
- package/plugins/src/base/agents/jira-agent.md +3 -1
- package/plugins/src/base/agents/jira-build-intake.md +2 -2
- package/plugins/src/base/agents/linear-agent.md +3 -1
- package/plugins/src/base/agents/linear-build-intake.md +2 -2
- package/plugins/src/base/rules/eager/intent-routing.md +2 -2
- package/plugins/src/base/rules/reference/intent-routing.md +4 -4
- package/plugins/src/base/skills/lisa-debrief/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-github-build-intake/SKILL.md +31 -35
- package/plugins/src/base/skills/lisa-implement/SKILL.md +6 -2
- package/plugins/src/base/skills/lisa-intake/SKILL.md +10 -16
- package/plugins/src/base/skills/lisa-jira-build-intake/SKILL.md +29 -33
- package/plugins/src/base/skills/lisa-linear-build-intake/SKILL.md +29 -33
- package/plugins/src/base/skills/lisa-monitor/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-plan/SKILL.md +6 -2
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +13 -42
- package/plugins/src/base/skills/lisa-research/SKILL.md +3 -1
- package/plugins/src/base/skills/lisa-verify/SKILL.md +3 -1
package/package.json
CHANGED
|
@@ -94,7 +94,7 @@
|
|
|
94
94
|
"ws": ">=8.20.1"
|
|
95
95
|
},
|
|
96
96
|
"name": "@codyswann/lisa",
|
|
97
|
-
"version": "2.198.
|
|
97
|
+
"version": "2.198.1",
|
|
98
98
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
99
99
|
"main": "dist/index.js",
|
|
100
100
|
"exports": {
|
|
@@ -10,7 +10,9 @@ Walk the original Plan for `$ARGUMENTS`, mine the completed work items and their
|
|
|
10
10
|
|
|
11
11
|
## Orchestration: agent team
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
You are "inside an agent team" only if you are yourself a spawned teammate or subagent — you were spawned into a team context, or your context names a team lead you report to. A lead/root session that has previously spawned subagents is still the lead and retains full authority to create this flow's team.
|
|
14
|
+
|
|
15
|
+
If you are NOT inside an agent team by that definition, the very first thing you do is establish team orchestration.
|
|
14
16
|
|
|
15
17
|
Use the team tool for the current runtime:
|
|
16
18
|
|
|
@@ -12,7 +12,7 @@ allowed-tools: ["Skill", "Bash"]
|
|
|
12
12
|
2. A full GitHub repo URL (e.g., `https://github.com/acme/frontend-v2`).
|
|
13
13
|
3. The literal token `github` — falls back to `.lisa.config.json` (`github.org` / `github.repo`).
|
|
14
14
|
|
|
15
|
-
Run one build-intake cycle. The first eligible issue in the configured `ready` build label is claimed, built via the `
|
|
15
|
+
Run one build-intake cycle. The first eligible issue in the configured `ready` build label is claimed, built via the `github-agent` workflow run in-session (Phase 3c, culminating in `lisa-implement`), relabeled to the configured `done` label (env-aware — see Workflow resolution), then the cycle exits. Remaining ready issues stay queued for later scheduler invocations.
|
|
16
16
|
|
|
17
17
|
This skill also accepts an optional `assignee=<github-login>` queue filter. Resolve it in this
|
|
18
18
|
order:
|
|
@@ -91,13 +91,13 @@ In prose below, the role names refer to the resolved labels: e.g. "the `ready` l
|
|
|
91
91
|
|
|
92
92
|
## Confirmation policy
|
|
93
93
|
|
|
94
|
-
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim and dispatch the first eligible issue through
|
|
94
|
+
Do NOT ask the caller whether to proceed. Once invoked with a repo, run the cycle to completion — claim and dispatch the first eligible issue through the in-session lifecycle (Phase 3c), relabel a successful build to `$DONE`, write the summary, and exit. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background queue.
|
|
95
95
|
|
|
96
96
|
Specifically forbidden:
|
|
97
97
|
|
|
98
98
|
- Previewing projected scope (issue count, projected PR count, build duration) and asking whether to continue.
|
|
99
99
|
- Offering A/B/C-style choices like "proceed / skip a few / dry-run only".
|
|
100
|
-
- Pausing because the queue is large, issues look complex, or issues are likely to be `Blocked` by
|
|
100
|
+
- Pausing because the queue is large, issues look complex, or issues are likely to be `Blocked` by the pre-flight gate. Pre-flight `Blocked` is a valid terminal state of the per-issue lifecycle, not a failure mode.
|
|
101
101
|
- Pausing because the build flow looks expensive.
|
|
102
102
|
|
|
103
103
|
The only legitimate reasons to stop early:
|
|
@@ -179,7 +179,7 @@ GitHub Issues live in one repo by definition, so the scanned repo's issues are u
|
|
|
179
179
|
|
|
180
180
|
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.**
|
|
181
181
|
|
|
182
|
-
Run this gate **before** the leaf claim relabel, starting with the oldest/highest-priority ready candidate. Do NOT comment "Claimed" or
|
|
182
|
+
Run this gate **before** the leaf claim relabel, starting with the oldest/highest-priority ready candidate. Do NOT comment "Claimed" or dispatch the lifecycle for an issue that fails the gate. A container repair still changes labels: remove `$READY`, add `$CLAIMED`, explain that parent/container `$CLAIMED` means rollup/build-lane progress through child/leaf work rather than direct implementation, record it, and end the cycle.
|
|
183
183
|
|
|
184
184
|
**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.
|
|
185
185
|
|
|
@@ -214,7 +214,7 @@ Classify and act (first match wins). `type:` is read from the issue's labels (`t
|
|
|
214
214
|
|
|
215
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
|
-
**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
|
|
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 dispatch the lifecycle. 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"
|
|
@@ -239,7 +239,7 @@ Default cleared blocker labels for GitHub build intake are:
|
|
|
239
239
|
- `status:on-stg`
|
|
240
240
|
- `status:done`
|
|
241
241
|
|
|
242
|
-
A blocker is active if it is open and has no cleared status label. Treat `status:ready`, `status:in-progress`, missing status labels, and inaccessible blockers as active. Closed blockers are cleared. If any blocker is active, skip the candidate without changing lifecycle labels, without posting "Claimed", and without
|
|
242
|
+
A blocker is active if it is open and has no cleared status label. Treat `status:ready`, `status:in-progress`, missing status labels, and inaccessible blockers as active. Closed blockers are cleared. If any blocker is active, skip the candidate without changing lifecycle labels, without posting "Claimed", and without dispatching the lifecycle. Record it under "Skipped (active blockers)" in the summary and include the active blocker refs. Keep any dependency-hold comment idempotent with a `[claude-build-intake]` prefix.
|
|
243
243
|
|
|
244
244
|
#### 3b. Claim
|
|
245
245
|
|
|
@@ -256,44 +256,40 @@ This is the idempotency lock — a re-entrant cycle's `--label $READY` filter wi
|
|
|
256
256
|
|
|
257
257
|
If the relabel fails (permission, race), log under "Errors" in the cycle summary and skip this issue. **Do not invoke the build flow on an issue you didn't successfully claim.**
|
|
258
258
|
|
|
259
|
-
#### 3c.
|
|
259
|
+
#### 3c. Run the per-issue lifecycle in-session (never as a subagent)
|
|
260
260
|
|
|
261
|
-
After the claim succeeds, the per-issue
|
|
261
|
+
After the claim succeeds, run the per-issue lifecycle defined by the `github-agent` workflow **in the current session** — never by spawning `github-agent` (or any named worker) via the `Agent` tool. The lifecycle culminates in a team-first flow (`lisa-implement`), and that flow can only create its agent team from the lead session: a spawned teammate cannot add named teammates (Claude teams are flat), so dispatching the build into a subagent strands `lisa-implement` without its team and collapses the build into a single inline worker. Concretely:
|
|
262
262
|
|
|
263
|
-
|
|
264
|
-
-
|
|
265
|
-
-
|
|
263
|
+
1. **Run the gates in-session** via their skills, exactly as `github-agent.md` defines them and with all of its gating behaviors intact:
|
|
264
|
+
- `lisa-github-read-issue` — the full issue graph (mandatory; never ad-hoc `gh` reads)
|
|
265
|
+
- `lisa-github-verify` — pre-flight quality gate, including the draft-then-block procedure on FAIL
|
|
266
|
+
- `lisa-ticket-triage` — analytical triage gate (a `BLOCKED` verdict stops the cycle with findings posted)
|
|
267
|
+
- Intent determination from the `type:` label
|
|
268
|
+
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <org>/<repo>#<number>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
269
|
+
3. **Milestone sync and evidence** (`lisa-github-sync`, `lisa-github-evidence`) happen at the milestones the `github-agent` workflow defines, within the dispatched flow.
|
|
266
270
|
|
|
267
|
-
Return this payload
|
|
271
|
+
If you are somehow running this skill as a spawned teammate inside an existing team (nested misrouting — Intake keeps this chain in the lead session), do NOT run the lifecycle inline and do NOT spawn named peers. Return this payload to the lead so the lead session can run this Phase 3c in-session:
|
|
268
272
|
|
|
269
273
|
```json
|
|
270
274
|
{
|
|
271
275
|
"type": "delegation-request",
|
|
272
|
-
"
|
|
276
|
+
"phase": "github-build-intake 3c",
|
|
273
277
|
"workItem": "<org>/<repo>#<number>",
|
|
274
278
|
"context": {
|
|
275
279
|
"claimedLabel": "$CLAIMED",
|
|
276
280
|
"doneResolution": "Resolve $DONE from the PR base branch per this skill's Workflow resolution section"
|
|
277
281
|
},
|
|
278
282
|
"onSuccess": "Confirm the returned PR is merged, then apply Phase 3d and Phase 3d.1",
|
|
279
|
-
"onBlockedOrError": "Leave the issue where
|
|
283
|
+
"onBlockedOrError": "Leave the issue where the lifecycle left it and record the surfaced outcome"
|
|
280
284
|
}
|
|
281
285
|
```
|
|
282
286
|
|
|
283
|
-
|
|
284
|
-
- Reading the full issue graph (`lisa-github-read-issue`)
|
|
285
|
-
- Running its own pre-flight quality gate (`lisa-github-verify`)
|
|
286
|
-
- Running issue triage (`lisa-ticket-triage`)
|
|
287
|
-
- Routing to the appropriate flow (Build / Fix / Investigate / Improve based on `type:` label)
|
|
288
|
-
- Posting progress comments via `lisa-github-sync`
|
|
289
|
-
- Posting evidence via `lisa-github-evidence`
|
|
290
|
-
|
|
291
|
-
The lead waits for `lisa-github-agent` to return, then resumes this scanner with the returned outcome:
|
|
287
|
+
The lifecycle run returns one of the following outcomes; resume this scanner with it:
|
|
292
288
|
|
|
293
289
|
- **Success** — the build flow completed and a PR exists; evidence posted. The PR may already be **merged** or still **open** (auto-merge enabled, awaiting checks/merge). "Success" means the build work is sound — it does **not** assert the change reached an environment. The env transition in 3d gates on the PR actually being merged; an open PR does not advance the issue to a `done` env status.
|
|
294
|
-
- **Blocked by github-verify pre-flight gate** —
|
|
295
|
-
- **Duplicate already fixed** — `lisa-
|
|
296
|
-
- **Blocked by ticket-triage ambiguities** —
|
|
290
|
+
- **Blocked by github-verify pre-flight gate** — the pre-flight gate (github-agent workflow step 2) relabels the issue to `status:blocked` (or removes `$CLAIMED` and reassigns to the original author). This is correct and expected — let it stand. Record and move on.
|
|
291
|
+
- **Duplicate already fixed** — `lisa-ticket-triage` returned `DUPLICATE_ALREADY_FIXED` with a canonical issue reference and empirical base-branch evidence. Post the triage finding, ensure the native `duplicates <canonical>` relationship exists when GitHub exposes it (otherwise leave an explicit cross-reference comment/body link), remove `$CLAIMED`, add the terminal `$DONE` label, close the issue with `gh issue close --reason "not planned"`, and do not open a PR. If the canonical fix is merged but not yet on the production branch, the close comment must say the production error can recur until the canonical issue promotes and that recurrence is tracked by the canonical issue; do not reopen this duplicate for that recurrence.
|
|
292
|
+
- **Blocked by ticket-triage ambiguities** — triage posts findings and the lifecycle stops. The issue stays in `$CLAIMED`. Surface to human; do not auto-relabel. Record under "Errors".
|
|
297
293
|
- **Errored** — exception, missing config, etc. Leave the issue in `$CLAIMED` for human investigation. Record under "Errors".
|
|
298
294
|
|
|
299
295
|
#### 3c.1 Close duplicate already fixed
|
|
@@ -320,7 +316,7 @@ This path is distinct from `BLOCKED`: ambiguity, open blockers, and duplicate-of
|
|
|
320
316
|
|
|
321
317
|
A `done` env state (`status:on-dev`, `status:on-stg`, or the terminal value) asserts that the code has actually reached that environment. Never set it for a PR that is merely open: auto-merge can be blocked indefinitely (a required rebase / `BEHIND` branch, failing checks, an unaddressed review), and the change may never land. Relabeling an issue `status:on-stg` on an open PR makes it *claim* a deploy that never happened. Transition only after confirming the PR merged.
|
|
322
318
|
|
|
323
|
-
If
|
|
319
|
+
If the lifecycle run returned Success:
|
|
324
320
|
|
|
325
321
|
1. **Confirm the PR merged.** Read the live state of the issue's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
326
322
|
- **Merged** (`state == MERGED`) → proceed to resolve and apply `$DONE` below. Where the env deploy is observable (a deploy workflow run / deployment status keyed to the merged-into branch via `deploy.branches`), confirm it did not fail before relabeling; a still-running deploy is treated like an open PR (leave in `$CLAIMED`), a failed deploy is recorded as an Error.
|
|
@@ -345,7 +341,7 @@ gh issue close <number> --repo <org>/<repo> --reason completed
|
|
|
345
341
|
|
|
346
342
|
This close is idempotent: if the issue is already closed, record that native closure was already satisfied and continue. If `$DONE` is an intermediate env state, leave the issue open by design.
|
|
347
343
|
|
|
348
|
-
For any non-Success outcome, do NOT transition. The issue sits in `$CLAIMED` (or wherever
|
|
344
|
+
For any non-Success outcome, do NOT transition. The issue sits in `$CLAIMED` (or wherever the lifecycle left it) — humans take it from there.
|
|
349
345
|
|
|
350
346
|
#### 3d.1 Roll up the parent chain (forward rollup)
|
|
351
347
|
|
|
@@ -376,7 +372,7 @@ Issues processed: <n>
|
|
|
376
372
|
- PR open — awaiting merge (left in $CLAIMED for repair-intake): <n>
|
|
377
373
|
- <org>/<repo>#<number> <title> → PR <URL> (mergeStateStatus: <state>)
|
|
378
374
|
- Repaired (container — leaf-only-lifecycle): <n>
|
|
379
|
-
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without
|
|
375
|
+
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without dispatching the lifecycle; lifecycle-repair comment posted
|
|
380
376
|
- Skipped (active blockers): <n>
|
|
381
377
|
- <org>/<repo>#<number> <title> — waiting on <blocker refs>
|
|
382
378
|
- Duplicate already fixed (closed as duplicate): <n>
|
|
@@ -395,8 +391,8 @@ Total PRs opened: <n>
|
|
|
395
391
|
|
|
396
392
|
- **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.
|
|
397
393
|
- **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.
|
|
398
|
-
- **Claim-first ordering**: `$CLAIMED` set BEFORE
|
|
399
|
-
- **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
|
|
394
|
+
- **Claim-first ordering**: `$CLAIMED` set BEFORE the lifecycle dispatch for leaves; containers are also moved to `$CLAIMED` to leave the ready pickup queue, but are not dispatched.
|
|
395
|
+
- **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 the per-issue lifecycle (github-agent workflow).
|
|
400
396
|
- **Duplicate terminal exception**: `DUPLICATE_ALREADY_FIXED` is the only triage outcome that may close a claimed item without a PR from this cycle. It must include a canonical issue reference and empirical base-branch evidence, and it closes as duplicate/not-planned rather than as completed build work.
|
|
401
397
|
- **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.
|
|
402
398
|
- **One item per cycle**: per-issue exceptions are caught and recorded, then the cycle exits. The scheduler owns retrying or moving on to the next ready item.
|
|
@@ -421,12 +417,12 @@ If the repo has not adopted the `status:*` label namespace, this skill cannot ru
|
|
|
421
417
|
|
|
422
418
|
- **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.
|
|
423
419
|
- 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.
|
|
424
|
-
- Never
|
|
420
|
+
- Never do build work directly from this scanner — the per-issue lifecycle (the `github-agent` workflow culminating in `lisa-implement`) owns it. And never spawn that lifecycle as a subagent; run it in-session per Phase 3c so `lisa-implement` can create its agent team.
|
|
425
421
|
- Never auto-transition past `$DONE`. Downstream labels (terminal `status:done`, etc.) are owned by QA / PM / merge automation.
|
|
426
422
|
- 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.
|
|
427
423
|
- Never auto-close a `BLOCKED`, ambiguous, or duplicate-of-open issue. Auto-close is allowed only for `DUPLICATE_ALREADY_FIXED`.
|
|
428
|
-
- If the issue has no Validation Journey or no sign-in credentials,
|
|
429
|
-
- On any unexpected
|
|
424
|
+
- If the issue has no Validation Journey or no sign-in credentials, the pre-flight verify gate will catch it — **don't try to fix the issue from here**.
|
|
425
|
+
- On any unexpected outcome from the lifecycle run (status it doesn't claim, missing PR URL on success), record as Error and surface — never assume.
|
|
430
426
|
- Never pick an arbitrary env for `$DONE` resolution. If `done` is a map and env is ambiguous, fail loudly.
|
|
431
427
|
|
|
432
428
|
## Adoption (one-time per repo)
|
|
@@ -9,7 +9,9 @@ description: "any non-trivial request —…"
|
|
|
9
9
|
|
|
10
10
|
Implement is a **team-first** flow. Bug, Build, Improve, and Investigate-Only all compose multiple specialists (Reproduce → debug → fix → review → verify). Single-agent mode is not permitted based on task complexity — the only exception is when no team creation or subagent delegation tool is available in the current runtime (see no-team fallback in the paragraph below).
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
You are "inside an agent team" only if you are yourself a spawned teammate or subagent — you were spawned into a team context, or your context names a team lead you report to. A lead/root session that has previously spawned subagents is still the lead: prior `Agent` calls in the session (e.g., an Intake cycle's bounded scan helpers) do NOT make this a nested flow, and the lead retains full authority to create this flow's team.
|
|
13
|
+
|
|
14
|
+
If you are NOT inside an agent team by that definition, the very first thing you do is establish team orchestration.
|
|
13
15
|
|
|
14
16
|
Use the team tool for the current runtime:
|
|
15
17
|
|
|
@@ -21,7 +23,9 @@ If no team creation or subagent delegation tool is available, explicitly state t
|
|
|
21
23
|
|
|
22
24
|
Your only permitted first move is establishing orchestration by spawning the bounded **input-resolver** teammate (Claude: `Agent`; Codex: `multi_agent_v1.spawn_agent`), or declaring the no-team fallback. The initial Claude `Agent` spawn is the only pre-team exception, and for Implement it must be the bounded input-resolver rather than a builder. Apart from that single spawn, do NOT call any of: a second `Agent`/`spawn_agent` for any worker, `TaskCreate`, `Skill` (including `lisa-tracker-read`, `lisa-jira-read-ticket`, `lisa-github-read-issue`), MCP tools (Atlassian / Linear / GitHub / Notion), `Read`, `Write`, `Edit`, `Bash`, `Grep`, `Glob` — until the input-resolver has returned and the Roster Decision has been recorded. Reading the ticket, exploring the code, fetching context — every one of those is a task for the team, not for the lead session before orchestration exists. Doing them inline, or spawning a single worker that does the whole build, is the exact bypass path that produces a 1-agent ad-hoc fix instead of a real team flow.
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
Note that `lisa-intake` dispatching this skill is NOT the nested case: Intake is a thin dispatcher that creates no team of its own and invokes this skill via the Skill tool in the lead session precisely so this preamble fires — treat an Intake dispatch exactly like a direct invocation and run the full team-first flow above.
|
|
27
|
+
|
|
28
|
+
If you ARE already inside an agent team by the definition above (you are a teammate that was handed this skill via the Skill tool from within another flow's team), do NOT create a second team — many harnesses reject double-creates — and do NOT collapse the nested flow into a single inline worker. A nested team-first flow must still bring in the specialists it requires by adding them to the existing team, not by doing the work itself:
|
|
25
29
|
|
|
26
30
|
- **Claude:** teams are flat and only the lead can add named teammates, so do NOT call `Agent` with a `name` from a teammate (the harness rejects it: *"Teammates cannot spawn other teammates — the team roster is flat"*). Send the team lead a message naming the specialist teammate(s) this flow needs, their task assignments, and completion criteria, then coordinate through the shared task list until they finish. An anonymous subagent (`Agent` with `name` omitted) is permitted only for bounded one-shot work whose result returns directly to you — it is not a substitute for the required lifecycle specialists.
|
|
27
31
|
- **Codex:** do NOT call `TeamCreate`. If the lead/root agent is addressable (you were given its id/handle), send it a request to `multi_agent_v1.spawn_agent` the specialist agent(s), including each agent's prompt, ownership, and expected result. If no lead handle exists but `spawn_agent` is available to you, spawn only the bounded specialist agent(s) this flow needs, `wait_agent` for their results, and relay those results upward to the parent/lead.
|
|
@@ -37,28 +37,22 @@ The only legitimate reasons to stop early:
|
|
|
37
37
|
- The queue itself is misconfigured (Status property missing expected values, JIRA workflow can't reach required transitions). Surface and exit.
|
|
38
38
|
- Empty `Ready` set. Exit cleanly with the idle-case message.
|
|
39
39
|
|
|
40
|
-
## Orchestration:
|
|
40
|
+
## Orchestration: thin dispatcher (no team of its own)
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
Intake creates NO agent team and spawns NO named teammates. It is a bounded scanner/dispatcher: resolve the queue, find the first eligible Ready item, claim it, and hand it to the single-item lifecycle skill — all in the current session.
|
|
43
43
|
|
|
44
|
-
|
|
44
|
+
This is deliberate. The per-item lifecycle skills (`lisa-plan` for PRDs, `lisa-implement` for build tickets) are team-first flows: each contains its own orchestration preamble that creates the agent team, records the roster, and fans out specialists. That preamble only has authority when the skill runs in the lead session — a teammate cannot add named teammates (Claude teams are flat: *"Teammates cannot spawn other teammates — the team roster is flat"*), so pushing the lifecycle skill down into a spawned subagent strands it without its team and collapses the flow into the single inline worker every team-first skill forbids. Therefore:
|
|
45
45
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
46
|
+
- **Scanning and claiming run inline in this session** (Bash / MCP / vendor skills via the Skill tool). This is cheap, bounded work — it does not need a team.
|
|
47
|
+
- **Per-item dispatch is a Skill-tool invocation in this same session — never an `Agent` spawn.** The chain Intake → vendor batch skill → lifecycle skill stays in the lead session end-to-end, so when `lisa-plan` / `lisa-implement` starts, its team-first preamble fires exactly as if the user had invoked it directly: it creates the per-item agent team, records the Roster Decision, and fans out its specialists.
|
|
48
|
+
- **Fresh context per item comes from the scheduler, not from subagent isolation.** Intake processes ONE eligible item per invocation and exits; each scheduled invocation is a fresh session. Never claim or process a second item after the first item's lifecycle flow has run in this session — exit and let the next cycle take it with clean context.
|
|
49
|
+
- The only permissible `Agent` use inside an Intake cycle is a bounded **anonymous** helper (`Agent` with `name` omitted) for scan-side legwork whose result returns directly to this session — e.g., paging a large queue. Never spawn the lifecycle flow, a vendor lifecycle agent (`jira-agent` / `github-agent` / `linear-agent`), or any implementation worker as a subagent from Intake.
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
Codex: the same contract applies — run the scan inline in the root session and invoke the lifecycle skill there so it can `multi_agent_v1.spawn_agent` its own team; do not `spawn_agent` the lifecycle flow itself. Other runtimes: apply the same rule through their equivalent delegation surface. If the runtime has no team/subagent tooling at all, the lifecycle skill's own no-team fallback handles it — Intake's job is unchanged.
|
|
51
52
|
|
|
52
|
-
|
|
53
|
+
If a teammate inside an existing team somehow invokes Intake (this should not happen — Intake is a session entry point, not a nested flow), do not scan or claim from there: return a structured `delegation-request` to the team lead asking it to run the Intake cycle in the lead session, and surface the misrouting.
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
- **Claude:** teams are flat and only the lead can add named teammates, so do NOT call `Agent` with a `name` from a teammate (the harness rejects it: *"Teammates cannot spawn other teammates — the team roster is flat"*). Send the team lead a message naming the specialist teammate(s) this flow needs, their task assignments, and completion criteria, then coordinate through the shared task list until they finish. An anonymous subagent (`Agent` with `name` omitted) is permitted only for bounded one-shot work whose result returns directly to you — it is not a substitute for the required lifecycle specialists.
|
|
57
|
-
- **Codex:** do NOT call `TeamCreate`. If the lead/root agent is addressable (you were given its id/handle), send it a request to `multi_agent_v1.spawn_agent` the specialist agent(s), including each agent's prompt, ownership, and expected result. If no lead handle exists but `spawn_agent` is available to you, spawn only the bounded specialist agent(s) this flow needs, `wait_agent` for their results, and relay those results upward to the parent/lead.
|
|
58
|
-
|
|
59
|
-
Treat the first successful lead-spawn request (or, on the Codex fallback, the first specialist spawn) as preserving team orchestration. Never satisfy a team-first lifecycle flow by doing all the work inline.
|
|
60
|
-
|
|
61
|
-
The cycle's outer team is created by Intake. The one item it processes (a PRD via `lisa-plan`, a ticket via `lisa-implement`) executes within that team — those skills' orchestration preambles detect the existing team and skip creating a second team. One team per cron cycle, one eligible Ready item per cycle.
|
|
55
|
+
One item per cycle. One team per item, created and owned by the lifecycle skill. A fresh session per cycle, provided by the scheduler.
|
|
62
56
|
|
|
63
57
|
## Source dispatch
|
|
64
58
|
|
|
@@ -13,7 +13,7 @@ All Atlassian operations in this skill go through `lisa-atlassian-access`. Do no
|
|
|
13
13
|
1. A JIRA project key (e.g. `SE`) — scans that project for tickets in the configured `ready` status.
|
|
14
14
|
2. A full JQL filter (e.g. `project = SE AND component = "frontend" AND Status = Ready`) — used as-is. The skill will not append a `Status = <ready>` clause if the JQL already names a status, so callers can intentionally widen. It also auto-scopes the query to the current repo (Phase 1 step 2) unless the JQL already constrains repo (a `repo:` label or `component =` term), so a multi-repo project / forwarded assignee filter is not widened to sibling repos by accident.
|
|
15
15
|
|
|
16
|
-
Run one build-intake cycle. The first eligible ready ticket is claimed, built via the `
|
|
16
|
+
Run one build-intake cycle. The first eligible ready ticket is claimed, built via the `jira-agent` workflow run in-session (Phase 3c, culminating in `lisa-implement`), transitioned to the configured `done` status (env-aware — see below), then the cycle exits. Remaining ready tickets stay queued for later scheduler invocations.
|
|
17
17
|
|
|
18
18
|
## Workflow resolution
|
|
19
19
|
|
|
@@ -68,17 +68,17 @@ else
|
|
|
68
68
|
fi
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
Run one build-intake cycle. The first eligible ticket in `$READY` is claimed by transitioning to `$CLAIMED`, built via the
|
|
71
|
+
Run one build-intake cycle. The first eligible ticket in `$READY` is claimed by transitioning to `$CLAIMED`, built via the in-session lifecycle (Phase 3c), transitioned to `$DONE` on completion, then the cycle exits.
|
|
72
72
|
|
|
73
73
|
## Confirmation policy
|
|
74
74
|
|
|
75
|
-
Do NOT ask the caller whether to proceed. Once invoked with a project key or JQL, run the cycle to completion — claim and dispatch the first eligible ticket through
|
|
75
|
+
Do NOT ask the caller whether to proceed. Once invoked with a project key or JQL, run the cycle to completion — claim and dispatch the first eligible ticket through the in-session lifecycle (Phase 3c), transition a successful build to `$DONE`, write the summary, and exit. The caller (a human or a cron) has already authorized the run by invoking the skill; re-prompting defeats the purpose of a background queue.
|
|
76
76
|
|
|
77
77
|
Specifically forbidden:
|
|
78
78
|
|
|
79
79
|
- Previewing projected scope (ticket count, projected PR count, build duration) and asking whether to continue.
|
|
80
80
|
- Offering A/B/C-style choices like "proceed / skip a few / dry-run only" — the documented behavior IS the default.
|
|
81
|
-
- Pausing because the queue is large, tickets look complex, or tickets are likely to be `Blocked` by
|
|
81
|
+
- Pausing because the queue is large, tickets look complex, or tickets are likely to be `Blocked` by the pre-flight gate. The pre-flight `Blocked` outcome is a valid terminal state of the per-ticket lifecycle, not a failure mode — surfacing those tickets to humans is success.
|
|
82
82
|
- Pausing because the build flow looks expensive. The cost of one cycle is bounded; the cost of stalling a scheduled cron waiting on a human is unbounded.
|
|
83
83
|
|
|
84
84
|
The only legitimate reasons to stop early:
|
|
@@ -155,7 +155,7 @@ A JIRA project can oversee multiple repos (`frontend` / `backend` / `infrastruct
|
|
|
155
155
|
|
|
156
156
|
Build intake claims **only independently implementable leaf work units**. This enforces the claim-time arm of the vendor-neutral `leaf-only-lifecycle` rule: a parent/container that still carries a stale build-ready status (e.g. `Ready` applied before this rule existed, or hand-applied to an Epic/Story) is **never claimed** — intake skips it or safe-blocks it with a clear lifecycle-repair message. It is the claim-time complement to the write-time labeling in `lisa-jira-write-ticket` and the validate-time S15 gate in `lisa-jira-validate-ticket`; all three cite the same rule so the classification never drifts. **Never silently implement a container.**
|
|
157
157
|
|
|
158
|
-
Run this gate **before** the claim transition, starting with the oldest/highest-priority ready candidate. Do NOT transition, comment "Claimed", or
|
|
158
|
+
Run this gate **before** the claim transition, starting with the oldest/highest-priority ready candidate. Do NOT transition, comment "Claimed", or dispatch the lifecycle for a ticket that fails the gate.
|
|
159
159
|
|
|
160
160
|
**Resolve container vs. leaf — structural first, then nominal.** Per `leaf-only-lifecycle` the classification is structural: a ticket is a **container** if it has **open** child work, whatever its declared type; otherwise the **issue type** decides. Resolve child work using the same hierarchy `lisa-jira-read-ticket` uses — JIRA's native Epic → Story → Sub-task parentage (Epic link / parent field for Stories under an Epic, and the subtask relationship for Sub-tasks under a Story/Task). Issue links (`blocks` / `is blocked by`) express cross-item dependencies and are **not** parentage — do not count them as children.
|
|
161
161
|
|
|
@@ -203,43 +203,39 @@ Transition the ticket from `$READY` to `$CLAIMED` by invoking `lisa-atlassian-ac
|
|
|
203
203
|
|
|
204
204
|
If the transition fails (permission, missing transition, race), log under "Errors" in the cycle summary and skip this ticket. **Do not invoke the build flow on a ticket you didn't successfully claim.**
|
|
205
205
|
|
|
206
|
-
#### 3c.
|
|
206
|
+
#### 3c. Run the per-ticket lifecycle in-session (never as a subagent)
|
|
207
207
|
|
|
208
|
-
After the claim succeeds, the per-ticket
|
|
208
|
+
After the claim succeeds, run the per-ticket lifecycle defined by the `jira-agent` workflow **in the current session** — never by spawning `jira-agent` (or any named worker) via the `Agent` tool. The lifecycle culminates in a team-first flow (`lisa-implement`), and that flow can only create its agent team from the lead session: a spawned teammate cannot add named teammates (Claude teams are flat), so dispatching the build into a subagent strands `lisa-implement` without its team and collapses the build into a single inline worker. Concretely:
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
210
|
+
1. **Run the gates in-session** via their skills, exactly as `jira-agent.md` defines them and with all of its gating behaviors intact:
|
|
211
|
+
- `lisa-jira-read-ticket` — the full ticket graph (mandatory; never ad-hoc reads)
|
|
212
|
+
- `lisa-jira-verify` — pre-flight quality gate, including the draft-then-block procedure on FAIL
|
|
213
|
+
- `lisa-ticket-triage` — analytical triage gate (a `BLOCKED` verdict stops the cycle with findings posted)
|
|
214
|
+
- Intent determination from the issue type
|
|
215
|
+
2. **Dispatch the flow in-session:** when the gates pass, invoke the lifecycle skill via the Skill tool — `lisa-implement <TICKET>` for Build / Fix / Improve / Investigate-Only (or `lisa-plan` for an Epic) — passing the full context bundle from the read step. `lisa-implement`'s own orchestration preamble then creates the per-item agent team (input-resolver, Roster Decision, specialist fanout) exactly as a direct invocation would.
|
|
216
|
+
3. **Milestone sync and evidence** (`lisa-jira-sync`, `lisa-jira-evidence`) happen at the milestones the `jira-agent` workflow defines, within the dispatched flow.
|
|
213
217
|
|
|
214
|
-
Return this payload
|
|
218
|
+
If you are somehow running this skill as a spawned teammate inside an existing team (nested misrouting — Intake keeps this chain in the lead session), do NOT run the lifecycle inline and do NOT spawn named peers. Return this payload to the lead so the lead session can run this Phase 3c in-session:
|
|
215
219
|
|
|
216
220
|
```json
|
|
217
221
|
{
|
|
218
222
|
"type": "delegation-request",
|
|
219
|
-
"
|
|
223
|
+
"phase": "jira-build-intake 3c",
|
|
220
224
|
"workItem": "<TICKET>",
|
|
221
225
|
"context": {
|
|
222
226
|
"claimedStatus": "$CLAIMED",
|
|
223
227
|
"doneResolution": "Resolve $DONE from the PR base branch per this skill's Workflow resolution section"
|
|
224
228
|
},
|
|
225
229
|
"onSuccess": "Confirm the returned PR is merged, then apply Phase 3d and Phase 3d.1",
|
|
226
|
-
"onBlockedOrError": "Leave the ticket where
|
|
230
|
+
"onBlockedOrError": "Leave the ticket where the lifecycle left it and record the surfaced outcome"
|
|
227
231
|
}
|
|
228
232
|
```
|
|
229
233
|
|
|
230
|
-
|
|
231
|
-
- Reading the full ticket graph (`lisa-jira-read-ticket`)
|
|
232
|
-
- Running its own pre-flight quality gate (`lisa-jira-verify`)
|
|
233
|
-
- Running ticket triage (`lisa-ticket-triage`)
|
|
234
|
-
- Routing to the appropriate flow (Build / Fix / Investigate / Improve based on type)
|
|
235
|
-
- Posting progress comments via `lisa-jira-sync`
|
|
236
|
-
- Posting evidence via `lisa-jira-evidence`
|
|
237
|
-
|
|
238
|
-
The lead waits for `lisa-jira-agent` to return, then resumes this scanner with the returned outcome:
|
|
234
|
+
The lifecycle run returns one of the following outcomes; resume this scanner with it:
|
|
239
235
|
- **Success** — the build flow completed and a PR exists; evidence posted. The PR may already be **merged** or still **open** (auto-merge enabled, awaiting checks/merge). "Success" means the build work is sound — it does **not** assert the change reached an environment. The env transition in 3d gates on the PR actually being merged; an open PR does not advance the ticket to a `done` env status.
|
|
240
|
-
- **Blocked by jira-verify pre-flight gate** —
|
|
241
|
-
- **Duplicate already fixed** — `lisa-
|
|
242
|
-
- **Blocked by ticket-triage ambiguities** —
|
|
236
|
+
- **Blocked by jira-verify pre-flight gate** — the pre-flight gate (jira-agent workflow step 2) transitions the ticket to `Blocked` and reassigns to Reporter. This is correct and expected — let it stand. Record the outcome and move on.
|
|
237
|
+
- **Duplicate already fixed** — `lisa-ticket-triage` returned `DUPLICATE_ALREADY_FIXED` with a canonical ticket reference and empirical base-branch evidence. Post the triage finding, ensure the native `duplicates <canonical>` link exists, transition to the terminal `$DONE` status with resolution `Duplicate`, and do not open a PR. If the canonical fix is merged but not yet on the production branch, the close comment must say the production error can recur until the canonical ticket promotes and that recurrence is tracked by the canonical ticket; do not reopen this duplicate for that recurrence.
|
|
238
|
+
- **Blocked by ticket-triage ambiguities** — triage posts findings and the lifecycle stops. The ticket stays in `$CLAIMED`. Surface to human; do not auto-transition. Record under "Errors" with reason `"Triage found ambiguities — see comments on <ticket-key>"`.
|
|
243
239
|
- **Errored** — exception, missing config, etc. Leave the ticket in `$CLAIMED` for human investigation. Record under "Errors" with the exception summary.
|
|
244
240
|
|
|
245
241
|
#### 3c.1 Close duplicate already fixed
|
|
@@ -261,7 +257,7 @@ This path is distinct from `BLOCKED`: ambiguity, open blockers, and duplicate-of
|
|
|
261
257
|
|
|
262
258
|
A `done` env status (`On Dev`, `On Stg`, or the terminal value) asserts that the code has actually reached that environment. Never set it for a PR that is merely open: auto-merge can be blocked indefinitely (a required rebase / `BEHIND` branch, failing checks, an unaddressed review), and the change may never land. Setting `On Stg` on an open PR makes a ticket *claim* a deploy that never happened. Transition only after confirming the PR merged.
|
|
263
259
|
|
|
264
|
-
If
|
|
260
|
+
If the lifecycle run returned Success:
|
|
265
261
|
1. **Confirm the PR merged.** Read the live state of the ticket's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
266
262
|
- **Merged** (`state == MERGED`) → proceed to resolve and apply `$DONE` below. Where the env deploy is observable (a deploy workflow run / deployment status keyed to the merged-into branch via `deploy.branches`), confirm it did not fail before transitioning; a still-running deploy is treated like an open PR (leave in `$CLAIMED` for a later cycle), a failed deploy is recorded as an Error.
|
|
267
263
|
- **Open / not yet merged** → do **not** transition. The build is sound but the change has reached no environment yet. Record the ticket under **"PR open — awaiting merge"** in the summary (with the PR URL and its `mergeStateStatus`), leave it in `$CLAIMED`, and stop. A later `lisa-repair-intake` cycle drives the open PR to merge — re-syncing a `BEHIND` branch so the already-enabled auto-merge can land, or surfacing a real blocker — and, once it is merged, applies this same env transition. Do **not** comment "Build complete" or file anything: the work is in-flight, not done.
|
|
@@ -275,7 +271,7 @@ If `lisa-jira-agent` returned Success:
|
|
|
275
271
|
5. If `$DONE` is terminal, verify the resulting JIRA issue is natively closed/resolved: status category is `Done`, and resolution is set when the project's workflow requires one. If the transition screen requires an explicit resolution, use the configured default resolution if present; otherwise record an Error naming the missing workflow setup rather than silently landing in an unresolved Done-named status.
|
|
276
272
|
6. Post a `[claude-build-intake]` comment via `lisa-atlassian-access` `operation: comment key: <TICKET> body: "Build complete. PR <URL> merged. Transitioned to $DONE."` Include whether terminal native resolution was verified, already satisfied, skipped for an intermediate env, or blocked by workflow setup.
|
|
277
273
|
|
|
278
|
-
For any non-Success outcome, do NOT transition. The ticket sits in `$CLAIMED` (or wherever
|
|
274
|
+
For any non-Success outcome, do NOT transition. The ticket sits in `$CLAIMED` (or wherever the lifecycle left it for the Blocked case) — the cycle's job is done; humans take it from there.
|
|
279
275
|
|
|
280
276
|
#### 3d.1 Roll up the parent chain (forward rollup)
|
|
281
277
|
|
|
@@ -322,8 +318,8 @@ Total PRs opened: <n>
|
|
|
322
318
|
## Idempotency & safety
|
|
323
319
|
|
|
324
320
|
- **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.
|
|
325
|
-
- **Claim-first ordering**: `$CLAIMED` set BEFORE
|
|
326
|
-
- **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
|
|
321
|
+
- **Claim-first ordering**: `$CLAIMED` set BEFORE the lifecycle dispatch — no double-pickup.
|
|
322
|
+
- **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 the per-ticket lifecycle (jira-agent workflow, which suggests transitions but only auto-transitions on the verify-FAIL path).
|
|
327
323
|
- **Duplicate terminal exception**: `DUPLICATE_ALREADY_FIXED` is the only triage outcome that may close a claimed ticket without a PR from this cycle. It must include a canonical ticket reference and empirical base-branch evidence, and it resolves as Duplicate rather than as completed build work.
|
|
328
324
|
- **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.
|
|
329
325
|
- **One item per cycle**: per-ticket exceptions are caught and recorded, then the cycle exits. The scheduler owns retrying or moving on to the next ready item.
|
|
@@ -360,9 +356,9 @@ If a ready-equivalent status does not exist in the JIRA project's workflow, this
|
|
|
360
356
|
- **Scope the query to the current repo.** Per `repo-scope-split`, append the repo pre-filter (Phase 1 step 2) so a multi-repo JIRA project — or a forwarded `assignee` filter — never pulls sibling repos' ready tickets into the candidate set. It is the cheap query-time arm of the same rule whose authoritative claim-time arm is the 3a.0 gate; the two must agree on how the current repo is resolved. Skip the augmentation (do not fail) only when the current repo can't be resolved or the JQL already constrains repo.
|
|
361
357
|
- **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.
|
|
362
358
|
- Never transition a ticket the cycle didn't claim. The `$CLAIMED` transition is the signature of cycle ownership.
|
|
363
|
-
- Never
|
|
359
|
+
- Never do build work directly from this scanner — the per-ticket lifecycle (the `jira-agent` workflow culminating in `lisa-implement`) owns it (read, verify, triage, route, sync, evidence). This skill is the dispatcher, not the builder. And never spawn that lifecycle as a subagent; run it in-session per Phase 3c so `lisa-implement` can create its agent team.
|
|
364
360
|
- Never auto-transition past `$DONE`. Downstream statuses are owned by QA / product / a future verification-intake skill — not this one.
|
|
365
361
|
- Never resolve / close a JIRA ticket at intermediate env statuses (`On Dev`, `On Stg`, or configured equivalents). Native resolution is terminal-only.
|
|
366
|
-
- If the ticket has no Validation Journey or no sign-in credentials in its description,
|
|
367
|
-
- On any unexpected
|
|
362
|
+
- If the ticket has no Validation Journey or no sign-in credentials in its description, the pre-flight verify gate will catch it and transition to `Blocked` — **don't try to fix the ticket from here**. Pre-flight gating is the lifecycle's job; running build work on a thin ticket produces broken work.
|
|
363
|
+
- On any unexpected outcome from the lifecycle run (status it doesn't claim, missing PR URL on success, etc.), record as Error and surface — never assume.
|
|
368
364
|
- Never pick an arbitrary env for `$DONE` resolution. If `done` is a map and env is ambiguous, fail loudly.
|