@codyswann/lisa 2.129.6 → 2.129.8
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/harper-fabric/copy-overwrite/knip.json +3 -0
- 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/skills/github-build-intake/SKILL.md +14 -6
- package/plugins/lisa/skills/jira-build-intake/SKILL.md +16 -8
- package/plugins/lisa/skills/linear-build-intake/SKILL.md +16 -8
- package/plugins/lisa/skills/repair-intake/SKILL.md +147 -31
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/github-build-intake/SKILL.md +14 -6
- package/plugins/lisa-agy/skills/jira-build-intake/SKILL.md +16 -8
- package/plugins/lisa-agy/skills/linear-build-intake/SKILL.md +16 -8
- package/plugins/lisa-agy/skills/repair-intake/SKILL.md +147 -31
- 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/skills/github-build-intake/SKILL.md +14 -6
- package/plugins/lisa-copilot/skills/jira-build-intake/SKILL.md +16 -8
- package/plugins/lisa-copilot/skills/linear-build-intake/SKILL.md +16 -8
- package/plugins/lisa-copilot/skills/repair-intake/SKILL.md +147 -31
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/github-build-intake/SKILL.md +14 -6
- package/plugins/lisa-cursor/skills/jira-build-intake/SKILL.md +16 -8
- package/plugins/lisa-cursor/skills/linear-build-intake/SKILL.md +16 -8
- package/plugins/lisa-cursor/skills/repair-intake/SKILL.md +147 -31
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/github-build-intake/SKILL.md +14 -6
- package/plugins/src/base/skills/jira-build-intake/SKILL.md +16 -8
- package/plugins/src/base/skills/linear-build-intake/SKILL.md +16 -8
- package/plugins/src/base/skills/repair-intake/SKILL.md +147 -31
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
"harper-app/resource-*.js",
|
|
18
18
|
"harper-app/web/**/*.js"
|
|
19
19
|
],
|
|
20
|
+
"ignoreIssues": {
|
|
21
|
+
"src/types/harper-schema.ts": ["types"]
|
|
22
|
+
},
|
|
20
23
|
"ignoreDependencies": ["@types/node", "@vitest/coverage-v8"],
|
|
21
24
|
"ignoreBinaries": ["audit", "harperdb", "knip", "playwright", "tsx"],
|
|
22
25
|
"rules": {
|
package/package.json
CHANGED
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"lodash": ">=4.18.1"
|
|
84
84
|
},
|
|
85
85
|
"name": "@codyswann/lisa",
|
|
86
|
-
"version": "2.129.
|
|
86
|
+
"version": "2.129.8",
|
|
87
87
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
88
88
|
"main": "dist/index.js",
|
|
89
89
|
"exports": {
|
|
@@ -264,24 +264,30 @@ Invoke `lisa:github-agent` (the per-issue lifecycle agent) with the issue ref. `
|
|
|
264
264
|
|
|
265
265
|
Wait for `lisa:github-agent` to return. Capture its outcome:
|
|
266
266
|
|
|
267
|
-
- **Success** — PR
|
|
267
|
+
- **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.
|
|
268
268
|
- **Blocked by github-verify pre-flight gate** — `lisa:github-agent` itself 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.
|
|
269
269
|
- **Blocked by ticket-triage ambiguities** — `lisa:github-agent` posts findings and stops. The issue stays in `$CLAIMED`. Surface to human; do not auto-relabel. Record under "Errors".
|
|
270
270
|
- **Errored** — exception, missing config, etc. Leave the issue in `$CLAIMED` for human investigation. Record under "Errors".
|
|
271
271
|
|
|
272
|
-
#### 3d. Transition to $DONE (only
|
|
272
|
+
#### 3d. Transition to $DONE (only after the PR is merged)
|
|
273
|
+
|
|
274
|
+
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.
|
|
273
275
|
|
|
274
276
|
If `lisa:github-agent` returned Success:
|
|
275
277
|
|
|
276
|
-
1.
|
|
277
|
-
|
|
278
|
+
1. **Confirm the PR merged.** Read the live state of the issue's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
279
|
+
- **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.
|
|
280
|
+
- **Open / not yet merged** → do **not** transition. The build is sound but the change has reached no environment yet. Record the issue 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 merged, applies this same env transition. Do **not** comment "Build complete" or close anything.
|
|
281
|
+
- **Closed without merging** → record an Error (the PR was abandoned unmerged); leave the issue in `$CLAIMED`.
|
|
282
|
+
2. Resolve `$DONE` for this issue's PR base branch using the Workflow resolution algorithm above. If env can't be resolved and `done` is env-keyed, record an Error and skip this transition — never guess.
|
|
283
|
+
3. Determine whether `$DONE` is the true terminal done value per the `leaf-only-lifecycle` rule's Terminal native closure section:
|
|
278
284
|
- If `github.labels.build.done` is a string, that string is terminal.
|
|
279
285
|
- If `github.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must stay open.
|
|
280
286
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not close.
|
|
281
287
|
|
|
282
288
|
```bash
|
|
283
289
|
gh issue edit <number> --repo <org>/<repo> --remove-label "$CLAIMED" --add-label "$DONE"
|
|
284
|
-
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Build complete. PR <URL
|
|
290
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Build complete. PR <URL> merged. Transitioned to $DONE."
|
|
285
291
|
```
|
|
286
292
|
|
|
287
293
|
If `$DONE` is terminal, immediately close the native GitHub issue:
|
|
@@ -308,8 +314,10 @@ Cycle started: <ISO timestamp>
|
|
|
308
314
|
Cycle completed: <ISO timestamp>
|
|
309
315
|
|
|
310
316
|
Issues processed: <n>
|
|
311
|
-
- $DONE (build complete, PR
|
|
317
|
+
- $DONE (build complete, PR merged): <n>
|
|
312
318
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
319
|
+
- PR open — awaiting merge (left in $CLAIMED for repair-intake): <n>
|
|
320
|
+
- <org>/<repo>#<number> <title> → PR <URL> (mergeStateStatus: <state>)
|
|
313
321
|
- Repaired (container — leaf-only-lifecycle): <n>
|
|
314
322
|
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without invoking lisa:github-agent; lifecycle-repair comment posted
|
|
315
323
|
- Skipped (active blockers): <n>
|
|
@@ -193,22 +193,28 @@ Invoke the `lisa:jira-agent` (existing per-ticket lifecycle agent) with the tick
|
|
|
193
193
|
- Posting evidence via `lisa:jira-evidence`
|
|
194
194
|
|
|
195
195
|
Wait for `lisa:jira-agent` to return. Capture its outcome:
|
|
196
|
-
- **Success** — PR
|
|
196
|
+
- **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.
|
|
197
197
|
- **Blocked by jira-verify pre-flight gate** — `lisa:jira-agent` itself transitions the ticket to `Blocked` and reassigns to Reporter. This is correct and expected — let it stand. Record the outcome and move on.
|
|
198
198
|
- **Blocked by ticket-triage ambiguities** — `lisa:jira-agent` posts findings and 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>"`.
|
|
199
199
|
- **Errored** — exception, missing config, etc. Leave the ticket in `$CLAIMED` for human investigation. Record under "Errors" with the exception summary.
|
|
200
200
|
|
|
201
|
-
#### 3d. Transition to $DONE (only
|
|
201
|
+
#### 3d. Transition to $DONE (only after the PR is merged)
|
|
202
|
+
|
|
203
|
+
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.
|
|
202
204
|
|
|
203
205
|
If `lisa:jira-agent` returned Success:
|
|
204
|
-
1.
|
|
205
|
-
|
|
206
|
+
1. **Confirm the PR merged.** Read the live state of the ticket's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
207
|
+
- **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.
|
|
208
|
+
- **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.
|
|
209
|
+
- **Closed without merging** → record an Error (the PR was abandoned unmerged); leave the ticket in `$CLAIMED` for human investigation.
|
|
210
|
+
2. Resolve `$DONE` for this ticket's PR base branch using the Workflow resolution algorithm above. If env can't be resolved and `done` is env-keyed, record an Error and skip this transition — never guess.
|
|
211
|
+
3. Determine whether `$DONE` is the true terminal done value per the `leaf-only-lifecycle` rule's Terminal native closure section:
|
|
206
212
|
- If `jira.workflow.done` is a string, that status is terminal.
|
|
207
213
|
- If `jira.workflow.done` is an object, only the production/final environment value is terminal (default: `Done`). Intermediate env statuses such as `On Dev` and `On Stg` are not terminal and must remain unresolved / open.
|
|
208
214
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not finalize native resolution.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
215
|
+
4. Invoke `lisa:atlassian-access` `operation: transition key: <TICKET> to: "$DONE"`.
|
|
216
|
+
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.
|
|
217
|
+
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.
|
|
212
218
|
|
|
213
219
|
For any non-Success outcome, do NOT transition. The ticket sits in `$CLAIMED` (or wherever `lisa:jira-agent` left it for the Blocked case) — the cycle's job is done; humans take it from there.
|
|
214
220
|
|
|
@@ -226,8 +232,10 @@ Cycle started: <ISO timestamp>
|
|
|
226
232
|
Cycle completed: <ISO timestamp>
|
|
227
233
|
|
|
228
234
|
Tickets processed: <n>
|
|
229
|
-
- $DONE (build complete, PR
|
|
235
|
+
- $DONE (build complete, PR merged): <n>
|
|
230
236
|
- <ticket-key> <summary> → PR <URL>
|
|
237
|
+
- PR open — awaiting merge (left in $CLAIMED for repair-intake): <n>
|
|
238
|
+
- <ticket-key> <summary> → PR <URL> (mergeStateStatus: <state>)
|
|
231
239
|
- Skipped (container — leaf-only-lifecycle): <n>
|
|
232
240
|
- <ticket-key> <summary> — build-ready on a parent with open child work; lifecycle-repair comment posted
|
|
233
241
|
- Blocked (pre-flight verify failed): <n>
|
|
@@ -203,22 +203,28 @@ Invoke `lisa:linear-agent` (per-Issue lifecycle agent) with the Issue identifier
|
|
|
203
203
|
- Posting evidence via `lisa:linear-evidence`
|
|
204
204
|
|
|
205
205
|
Wait for the agent to return. Capture its outcome:
|
|
206
|
-
- **Success** — PR
|
|
206
|
+
- **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.
|
|
207
207
|
- **Blocked by linear-verify pre-flight gate** — `lisa:linear-agent` itself relabels to `status:blocked` and assigns to creator. Let it stand. Record and move on.
|
|
208
208
|
- **Blocked by ticket-triage ambiguities** — agent posts findings and stops. The Issue stays at `$CLAIMED`. Surface to human; do not auto-transition. Record under "Errors".
|
|
209
209
|
- **Errored** — exception, missing config, etc. Leave at `$CLAIMED`. Record with exception summary.
|
|
210
210
|
|
|
211
|
-
#### 3d. Relabel to $DONE (only
|
|
211
|
+
#### 3d. Relabel to $DONE (only after the PR is merged)
|
|
212
|
+
|
|
213
|
+
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.
|
|
212
214
|
|
|
213
215
|
If `lisa:linear-agent` returned Success:
|
|
214
|
-
1.
|
|
215
|
-
|
|
216
|
+
1. **Confirm the PR merged.** Read the live state of the Issue's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
217
|
+
- **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 at `$CLAIMED`), a failed deploy is recorded as an Error.
|
|
218
|
+
- **Open / not yet merged** → do **not** transition. The build is sound but the change has reached no environment yet. Record the Issue under **"PR open — awaiting merge"** in the summary (with the PR URL and its `mergeStateStatus`), leave it at `$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 merged, applies this same env transition. Do **not** comment "Build complete" or change the native state.
|
|
219
|
+
- **Closed without merging** → record an Error (the PR was abandoned unmerged); leave the Issue at `$CLAIMED`.
|
|
220
|
+
2. Resolve `$DONE` for this issue's PR base branch using the Workflow resolution algorithm above. If env can't be resolved and `done` is env-keyed, record an Error and skip this transition — never guess.
|
|
221
|
+
3. Determine whether `$DONE` is the true terminal done value per the `leaf-only-lifecycle` rule's Terminal native closure section:
|
|
216
222
|
- If `linear.labels.build.done` is a string, that string is terminal.
|
|
217
223
|
- If `linear.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must keep the native Issue open.
|
|
218
224
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not change the native state.
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
225
|
+
4. Update labels via `mcp__linear-server__save_issue`: remove `$CLAIMED` (or `$REVIEW` if `lisa:linear-evidence` already moved it forward), add `$DONE`.
|
|
226
|
+
5. If `$DONE` is terminal, move the native Linear Issue state to the configured Done / Completed state. Resolve that state from project configuration if present; otherwise inspect the team workflow for a terminal state with `state.type = "completed"` and a name such as `Done` or `Completed`. If no terminal state can be resolved, record an Error and leave the labels as the source of truth — do not invent a state name.
|
|
227
|
+
6. Post a `[claude-build-intake]` comment: `"Build complete. PR <URL> merged. Transitioned to $DONE."` Include whether native closure was applied, already satisfied, skipped for an intermediate env, or unavailable for setup reasons.
|
|
222
228
|
|
|
223
229
|
For any non-Success outcome, do NOT transition. The Issue sits where the agent left it — humans take it from there.
|
|
224
230
|
|
|
@@ -236,8 +242,10 @@ Cycle started: <ISO timestamp>
|
|
|
236
242
|
Cycle completed: <ISO timestamp>
|
|
237
243
|
|
|
238
244
|
Issues processed: <n>
|
|
239
|
-
- $DONE (build complete, PR
|
|
245
|
+
- $DONE (build complete, PR merged): <n>
|
|
240
246
|
- <ID> <title> → PR <URL>
|
|
247
|
+
- PR open — awaiting merge (left at $CLAIMED for repair-intake): <n>
|
|
248
|
+
- <ID> <title> → PR <URL> (mergeStateStatus: <state>)
|
|
241
249
|
- Skipped (container — leaf-only-lifecycle): <n>
|
|
242
250
|
- <ID> <title> — build-ready on a parent with open child work; lifecycle-repair comment posted
|
|
243
251
|
- status:blocked (pre-flight verify failed): <n>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: repair-intake
|
|
3
|
-
description: "Vendor-agnostic repair scanner — the recovery counterpart to lisa:intake. Where intake claims `ready` work, repair-intake finds work that got stuck or was left half-closed: items left in `blocked`, stalled in an in-progress role (build `claimed`, PRD `in_review`), terminal-labeled items that are still natively open, and rollup/container items whose children are all terminal but whose parent is not closed out. Scans the same queues lisa:intake serves (Notion / Confluence / Linear / GitHub PRD databases; JIRA / GitHub / Linear build queues), enumerates candidates up to `max_candidates`, and repairs every materially actionable one in that bounded set: resumes stalled in-progress work IN PLACE (build → the vendor agent + the scanner's post-agent transition; PRD → the source `*-to-tracker` dry-run validate→route pipeline) — but for a stalled build it first diagnoses the PR/deploy state
|
|
3
|
+
description: "Vendor-agnostic repair scanner — the recovery counterpart to lisa:intake. Where intake claims `ready` work, repair-intake finds work that got stuck or was left half-closed: items left in `blocked`, stalled in an in-progress role (build `claimed`, PRD `in_review`), terminal-labeled items that are still natively open, and rollup/container items whose children are all terminal but whose parent is not closed out. Scans the same queues lisa:intake serves (Notion / Confluence / Linear / GitHub PRD databases; JIRA / GitHub / Linear build queues), enumerates candidates up to `max_candidates`, and repairs every materially actionable one in that bounded set: resumes stalled in-progress work IN PLACE (build → the vendor agent + the scanner's post-agent transition; PRD → the source `*-to-tracker` dry-run validate→route pipeline) — but for a stalled build it first diagnoses the PR/deploy state: a PR that already merged is recovered by applying the env transition build-intake never got to (no re-dispatch); a PR that is merely behind its base is re-synced in place via `gh pr update-branch` so the already-enabled auto-merge can land (a clean rebase needs no human); and only a PR that cannot merge for a non-mechanical reason (true conflict, failing checks, unaddressed CodeRabbit/changes-requested) or a failed deploy gets a build-ready leaf fix ticket with the item moved to `blocked` (blocked by that ticket) rather than re-dispatching, re-validates blocked PRDs when new clarifying answers exist, re-dispatches blocked build items whose `is blocked by` dependencies have since closed OR whose validation/quality-gate self-block now re-validates PASS (re-running `lisa:tracker-validate` against current content — the build mirror of PRD re-validation), performs terminal native closure for terminal-labeled items, reconciles parent rollups to their derived state per leaf-only-lifecycle — including the intermediate-env case (e.g. all children at `On Stg` → parent `On Stg`) and a container wrongly stuck in `ready` — and closes out rollups whose associated child work is fully terminal. Idempotent, loop-protected via a [lisa-repair-intake] marker + state fingerprint + backoff. Never mutates product-owned states (`draft`, `verified`) and never touches `ready` leaves (a container wrongly carrying `ready` is the one exception — it is rolled up from its children, since `ready` on a parent is an invariant violation, not intake's claim signal). Designed as a /schedule cron target running alongside lisa:intake."
|
|
4
4
|
allowed-tools: ["Skill", "Bash", "Read", "Write", "Edit", "mcp__linear-server__list_teams", "mcp__linear-server__list_projects", "mcp__linear-server__get_project", "mcp__linear-server__save_project", "mcp__linear-server__list_project_labels", "mcp__linear-server__list_issues", "mcp__linear-server__get_issue", "mcp__linear-server__save_issue", "mcp__linear-server__list_comments", "mcp__linear-server__save_comment", "mcp__linear-server__list_issue_labels", "mcp__linear-server__create_issue_label"]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -15,13 +15,24 @@ close-out** roles and moves work *unstuck* or *fully closed*:
|
|
|
15
15
|
happening, so it sits ignored forever. (The vendor PRD intakes explicitly leave an errored PRD
|
|
16
16
|
in `in_review` "for the human to investigate from there" — that orphan is exactly what this
|
|
17
17
|
skill recovers.) For a stalled **build**, repair-intake first diagnoses *why* it stalled by
|
|
18
|
-
inspecting its PRs and deploys
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
inspecting its PRs and deploys. A PR that **already merged** is recovered by applying the env
|
|
19
|
+
transition build-intake never got to (its merge gate left the item `claimed` when the merge landed
|
|
20
|
+
after its agent returned) — no re-dispatch. A PR that is merely **behind its base** (`BEHIND`, no
|
|
21
|
+
conflict) is **re-synced in place** with `gh pr update-branch` so the already-enabled auto-merge can
|
|
22
|
+
finally land — a clean rebase needs no human, and leaving it stranded is the exact gap that lets an
|
|
23
|
+
auto-merge PR sit unmerged forever. Only a PR that cannot merge for a non-mechanical reason (true
|
|
24
|
+
conflict / failing checks / unaddressed CodeRabbit or `CHANGES_REQUESTED` review) or a failed deploy
|
|
25
|
+
gets a build-ready leaf fix ticket with the item moved to `blocked` (blocked by that ticket) instead
|
|
26
|
+
of blindly re-dispatching the agent — which would just churn against an unmergeable PR.
|
|
27
|
+
- **Recoverable blocked** — an item in `blocked` whose blocker may now be gone. The blocker is
|
|
28
|
+
one of three classes, and repair re-checks **all** of them, not just dependencies: (a) an
|
|
29
|
+
`is blocked by` **dependency** has since closed; (b) a **validation / quality-gate self-block** —
|
|
30
|
+
the item was bounced to `blocked` by its own pre-flight `verify`/`validate` gate (missing
|
|
31
|
+
Validation Journey, Sign-in Required, Acceptance Criteria, etc.) with **no dependency at all**,
|
|
32
|
+
and a human has since edited the item to add what the gate demanded; or (c) **clarifying
|
|
33
|
+
questions answered** / an **ambiguity** research can now settle. A self-block (b) is the common
|
|
34
|
+
one missed by dependency-only re-checks: nothing else is blocking it, so re-running the same gate
|
|
35
|
+
against its current content is the only way to know it is now passable.
|
|
25
36
|
- **Terminal-open drift** — an item already carrying its true terminal lifecycle role (for
|
|
26
37
|
example GitHub `status:done`) but still open/active in the provider's native state.
|
|
27
38
|
- **Rollup drift** — a parent/container item (Epic, Story, PRD, Linear Project, or equivalent)
|
|
@@ -251,14 +262,24 @@ deploys (see "Stuck-cause diagnosis" below). A stalled build usually stalled for
|
|
|
251
262
|
reason, and re-dispatching the agent at it will not fix a PR that cannot merge or a deploy that
|
|
252
263
|
failed — it just churns.
|
|
253
264
|
|
|
254
|
-
0. **Diagnose PR & deploy
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
265
|
+
0. **Diagnose PR & deploy state.** Run "Stuck-cause diagnosis" below. It resolves, in order:
|
|
266
|
+
- **PR already merged** → the build effectively completed; the vendor build-intake's merge gate
|
|
267
|
+
left the item `claimed` because the merge landed after its agent returned. Do **not** re-dispatch
|
|
268
|
+
or file anything — apply the scanner's post-agent env-resolved `claimed → done` transition
|
|
269
|
+
directly (step 2 below, env-resolved), and record it. This is the recovery arm for build-intake
|
|
270
|
+
leaving merged-but-unadvanced items in `claimed`.
|
|
271
|
+
- **PR only behind its base (a needed rebase)** → mechanically resolvable, **not** a human blocker.
|
|
272
|
+
Re-sync the branch in place so the already-enabled auto-merge can land (see diagnosis step 3).
|
|
273
|
+
Keep the item `claimed`; a later cycle confirms the merge and transitions. Do **not** file a fix
|
|
274
|
+
ticket for a clean rebase.
|
|
275
|
+
- **A real external blocker** (PR cannot merge for a non-mechanical reason — true merge conflict /
|
|
276
|
+
failing checks / `CHANGES_REQUESTED` / unaddressed CodeRabbit; or a failed deploy) → **do not
|
|
277
|
+
dispatch the agent**. File a build-ready leaf fix ticket for the blocker, move this item
|
|
278
|
+
`claimed → blocked` with an `is blocked by` link to that ticket, and record it. The existing
|
|
279
|
+
"Build `blocked` → unblock if cleared" path resumes this item on a later cycle once the fix
|
|
280
|
+
ticket is terminal — a self-healing loop. Skip the resume steps below.
|
|
281
|
+
|
|
282
|
+
If the PR is healthy in-flight and no blocker is found, the work simply died mid-flight — run the **same per-item sequence
|
|
262
283
|
the vendor build-intake runs**, skipping the claim transition (the item is already `claimed`):
|
|
263
284
|
|
|
264
285
|
1. Dispatch the item to the vendor agent — `lisa:jira-agent` / `lisa:github-agent` /
|
|
@@ -287,12 +308,38 @@ external state that resuming the agent cannot fix."
|
|
|
287
308
|
links and `gh pr list --search <issue-ref>`; JIRA: dev-status / remote links; Linear: attachments
|
|
288
309
|
and git-branch links) and the deploy(s) for the resulting merge (the env-keyed `deploy.branches`
|
|
289
310
|
mapping from `config-resolution`). Read each PR with the vendor's native state, e.g. GitHub
|
|
290
|
-
`gh pr view <n> --json mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments,reviews`.
|
|
311
|
+
`gh pr view <n> --json state,mergedAt,mergeable,mergeStateStatus,reviewDecision,statusCheckRollup,comments,reviews`.
|
|
312
|
+
|
|
313
|
+
**2. PR already merged → recover, don't re-dispatch.** If `state == MERGED`, the build is effectively
|
|
314
|
+
complete and the only thing missing is the env transition the build-intake never applied (its merge
|
|
315
|
+
gate left the item `claimed` because the merge landed after its agent returned). Do **not** re-dispatch
|
|
316
|
+
or file anything: apply the scanner's post-agent env-resolved `claimed → done` transition (the
|
|
317
|
+
resume-sequence step 2, env-resolved from the merged PR's base branch) and record it as a repair
|
|
318
|
+
write. Where the env deploy is observable, confirm it did not fail first; a failed post-merge deploy
|
|
319
|
+
falls through to the blocker path (step 4).
|
|
320
|
+
|
|
321
|
+
**3. PR only behind its base → re-sync in place (mechanical, not a blocker).** If the PR is clean but
|
|
322
|
+
behind its base — `mergeStateStatus == BEHIND` while `mergeable != CONFLICTING` and no required check
|
|
323
|
+
is failing — it does **not** need a human. This is exactly the case that strands a PR forever: GitHub
|
|
324
|
+
auto-merge will not advance a `BEHIND` branch on its own, so a PR opened with `--auto` sits unmerged
|
|
325
|
+
until something rebases it. Re-sync it in place and let the existing auto-merge land it:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
gh pr update-branch <n> # rebase/merge the base into the PR head; reruns required checks
|
|
329
|
+
```
|
|
291
330
|
|
|
292
|
-
|
|
331
|
+
Record this as a repair write (`resynced`), keep the item `claimed`, and move on — a later cycle sees
|
|
332
|
+
the now-`CLEAN` (or merged) PR and either lets auto-merge finish or applies the merged-PR recovery in
|
|
333
|
+
step 2. Only if `gh pr update-branch` itself reports a conflict it cannot apply does the PR become a
|
|
334
|
+
true conflict (step 4). Honor the backoff window so repeated cycles don't re-issue `update-branch` on
|
|
335
|
+
an unchanged head (Loop prevention). For JIRA/Linear items the PR is still the GitHub PR backing the
|
|
336
|
+
branch — operate on it the same way.
|
|
293
337
|
|
|
294
|
-
|
|
295
|
-
|
|
338
|
+
**4. Classify as a blocker.** Treat any of these as a real external blocker:
|
|
339
|
+
|
|
340
|
+
- **True merge conflict** — `mergeable = CONFLICTING` or `mergeStateStatus = DIRTY` (overlapping
|
|
341
|
+
changes a plain rebase cannot resolve), or `gh pr update-branch` (step 3) reported a conflict. A
|
|
342
|
+
merely `BEHIND` branch is **not** here — it was re-synced in step 3.
|
|
296
343
|
- **Failing required checks** — `statusCheckRollup` has a `FAILURE`/`ERROR`/`TIMED_OUT` conclusion,
|
|
297
344
|
or `mergeStateStatus = UNSTABLE`/`BLOCKED` due to checks.
|
|
298
345
|
- **Change requests outstanding** — `reviewDecision = CHANGES_REQUESTED`, or unresolved CodeRabbit
|
|
@@ -306,7 +353,7 @@ A check that is still **queued/in progress**, or a `CLEAN`/`HAS_HOOKS` mergeable
|
|
|
306
353
|
outstanding change request, is **not** a blocker — that is normal in-flight state. (Such a PR with
|
|
307
354
|
recent check/commit activity would already have been caught as `active` by the staleness gate.)
|
|
308
355
|
|
|
309
|
-
**
|
|
356
|
+
**5. On a blocker found → file a leaf fix ticket + block the item.**
|
|
310
357
|
|
|
311
358
|
1. **File one build-ready leaf fix ticket** per distinct blocker via `lisa:tracker-write` (the
|
|
312
359
|
vendor-neutral leaf writer + validation gate; never a vendor `*-write-*` skill directly),
|
|
@@ -332,14 +379,31 @@ window and state fingerprint (Loop prevention) so re-runs over the same unchange
|
|
|
332
379
|
|
|
333
380
|
### Build `blocked` → re-evaluate, unblock if cleared
|
|
334
381
|
|
|
335
|
-
1. Read the block reason and
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
382
|
+
1. Read the block reason and classify the blocker (see Blocker classification & clearing). An item
|
|
383
|
+
may be held by a **dependency**, by a **validation / quality-gate self-block**, by an
|
|
384
|
+
**ambiguity**, or by more than one at once. Re-check **every** class present — do not stop at
|
|
385
|
+
"no `is blocked by` links, therefore nothing to do." A self-block has zero dependencies by
|
|
386
|
+
definition, yet is fully re-checkable.
|
|
387
|
+
2. **Dependency cleared** — if every parsed `is blocked by` dependency is **cleared** → move
|
|
388
|
+
`blocked → claimed`, then run the same agent-dispatch + post-agent `claimed → done` sequence as
|
|
389
|
+
the stalled-`claimed` path above (one-cycle recovery). If the agent re-blocks, move back to
|
|
390
|
+
`blocked` — a valid outcome.
|
|
391
|
+
3. **Validation / quality-gate self-block re-check** — if the block reason is a pre-flight
|
|
392
|
+
`verify`/`validate` gate failure (its `[lisa-*]` block note carries a gate marker + a "Missing
|
|
393
|
+
requirements" list and there is **no** open `is blocked by` dependency), re-run the **same gate**
|
|
394
|
+
against the item's **current** content via `lisa:tracker-validate` (read-only; the vendor-neutral
|
|
395
|
+
gate `lisa:<tracker>-build-intake` and `lisa:<tracker>-write-*` already use). This is the build
|
|
396
|
+
mirror of the PRD `blocked → re-validate` path below.
|
|
397
|
+
- **PASS now** (the human added what was missing) → move `blocked → claimed` and resume exactly
|
|
398
|
+
as in (2): agent-dispatch + post-agent `claimed → done`.
|
|
399
|
+
- **Still FAIL** → stay `blocked`, but refresh the note with the **current** (usually smaller)
|
|
400
|
+
missing-requirement set so the human sees what remains. Because the fingerprint includes the
|
|
401
|
+
gate verdict + missing-requirement set (Loop prevention), a partial human fix changes the
|
|
402
|
+
fingerprint and re-checks next cycle, while a truly-unchanged gate result stays in backoff.
|
|
403
|
+
4. If the block was an **ambiguity** research can settle and no dependency remains → run the
|
|
340
404
|
research needed (`lisa:codebase-research` / `lisa:product-walkthrough`); if resolved, proceed
|
|
341
405
|
as in (2).
|
|
342
|
-
|
|
406
|
+
5. Else → still blocked. Refresh the note with the current reason (Loop prevention) and leave it
|
|
343
407
|
`blocked`.
|
|
344
408
|
|
|
345
409
|
### Build terminal-open → native close / complete / resolve
|
|
@@ -460,7 +524,13 @@ work is fully terminal:
|
|
|
460
524
|
5. If generated work is missing, ambiguous, or partially incomplete, leave the PRD open and report
|
|
461
525
|
the incomplete child set. Never close a PRD on partial completion.
|
|
462
526
|
|
|
463
|
-
##
|
|
527
|
+
## Blocker classification & clearing (conservative, vendor-specific extraction)
|
|
528
|
+
|
|
529
|
+
A `blocked` build item is held by one or more of three blocker classes. Identify which are present
|
|
530
|
+
from the item's block note(s) and links, then clear-check **each present class** — an item with no
|
|
531
|
+
dependency is not automatically un-actionable; it may be a self-block that now passes.
|
|
532
|
+
|
|
533
|
+
### Class A — dependency blockers
|
|
464
534
|
|
|
465
535
|
`lisa:tracker-read` is a thin dispatcher that returns each vendor's bundle **verbatim** — there
|
|
466
536
|
is no normalized `is blocked by` field. Read the bundle, then extract blockers per vendor:
|
|
@@ -485,6 +555,38 @@ Only re-dispatch when **every** parsed blocker is cleared. When in doubt, stay b
|
|
|
485
555
|
false-negative (left blocked) is cheap; a false-positive (re-dispatched into a real blocker)
|
|
486
556
|
wastes a build cycle.
|
|
487
557
|
|
|
558
|
+
### Class B — validation / quality-gate self-block
|
|
559
|
+
|
|
560
|
+
A self-block has **no** `is blocked by` dependency: the build-intake/agent flow claimed the item,
|
|
561
|
+
its pre-flight `verify`/`validate` gate failed (missing Validation Journey, Sign-in Required,
|
|
562
|
+
Target Backend Environment, Repository, Out of Scope, Evidence manifest, weak Acceptance Criteria,
|
|
563
|
+
etc.), and the item was bounced to `blocked` carrying that gate's `[lisa-*]` note + "Missing
|
|
564
|
+
requirements" list. Detect it by: (1) the block note bears a known gate marker (e.g.
|
|
565
|
+
`Pre-flight verify gate: BLOCKED`, `jira-verify` / `*-validate-*`), **and** (2) there is no open
|
|
566
|
+
`is blocked by` dependency. (If both a dependency and a self-block are present, clear the
|
|
567
|
+
dependency via Class A first; the self-block re-check still gates the eventual re-dispatch.)
|
|
568
|
+
|
|
569
|
+
Clear-check by **re-running the same gate against current content** — `lisa:tracker-validate`
|
|
570
|
+
(read-only; never writes), which dispatches to `lisa:<tracker>-validate-*` exactly as the write
|
|
571
|
+
path and build-intake do, so the bar cannot drift:
|
|
572
|
+
|
|
573
|
+
- **PASS** → cleared. Proceed to re-dispatch (decision tree step 2).
|
|
574
|
+
- **FAIL** → still self-blocked. Refresh the note with the current missing set (Loop prevention).
|
|
575
|
+
|
|
576
|
+
Conservative, same as Class A: a still-failing gate is a real blocker — never re-dispatch a build
|
|
577
|
+
whose own gate has not yet passed. This is intentionally symmetric with the PRD `blocked →
|
|
578
|
+
re-validate` path: PRDs re-run their dry-run `validate→route` when source content changes; builds
|
|
579
|
+
re-run `tracker-validate` when item content changes. The asymmetry where build `blocked` checked
|
|
580
|
+
only dependencies — leaving verify-gate self-blocks stranded forever after a human filled in the
|
|
581
|
+
missing sections — is the gap this class closes.
|
|
582
|
+
|
|
583
|
+
### Class C — ambiguity / clarifying answers
|
|
584
|
+
|
|
585
|
+
A block that research or a human answer can settle (no dependency, no failing gate). Re-check by
|
|
586
|
+
running the needed research (`lisa:codebase-research` / `lisa:product-walkthrough`) or detecting a
|
|
587
|
+
human comment/edit newer than the last `[lisa-repair-intake]` note. Resolved → proceed to
|
|
588
|
+
re-dispatch; else stay blocked.
|
|
589
|
+
|
|
488
590
|
## Loop prevention
|
|
489
591
|
|
|
490
592
|
A `blocked` item with a permanently unresolved problem must not be "repaired" and re-noted every
|
|
@@ -492,7 +594,10 @@ cron tick.
|
|
|
492
594
|
|
|
493
595
|
- Every note this skill writes is prefixed `[lisa-repair-intake]` and carries a compact **state
|
|
494
596
|
fingerprint**: the lifecycle role, the set of blocker refs + their observed states, the
|
|
495
|
-
validation verdict (PASS/FAIL)
|
|
597
|
+
validation verdict (PASS/FAIL) **plus the current missing-requirement set for a Class-B
|
|
598
|
+
self-block** (so a human filling in one of several missing sections changes the fingerprint and
|
|
599
|
+
triggers a re-check next cycle, rather than being suppressed as a no-op), terminal/open state,
|
|
600
|
+
rollup child tally, and a timestamp.
|
|
496
601
|
- Before writing a note or re-attempting a `blocked` item, compute the current fingerprint. If
|
|
497
602
|
an identical fingerprint was already posted within the **backoff window**, skip the item
|
|
498
603
|
silently (record as `still_blocked` / `active`, no write).
|
|
@@ -548,8 +653,10 @@ It MUST NOT:
|
|
|
548
653
|
containers, that need their derived state applied (status-only reconciliation, no native
|
|
549
654
|
close),
|
|
550
655
|
4. `blocked` items whose dependencies are now **cleared** (safe, high-value, one-cycle wins),
|
|
551
|
-
5. `blocked` items
|
|
552
|
-
|
|
656
|
+
5. `blocked` items whose **validation / quality-gate self-block now re-validates PASS** —
|
|
657
|
+
a human filled in the missing sections (Class B; equally safe and high-value),
|
|
658
|
+
6. `blocked` items with **new clarifying answers**,
|
|
659
|
+
7. **stalled** in-progress items, oldest activity first.
|
|
553
660
|
4. **Walk the ordered list**, evaluating each candidate (terminal close-out, rollup child tally,
|
|
554
661
|
staleness, dependency, answer checks), and repair **every** candidate that is actionable inside
|
|
555
662
|
the `max_candidates` cap. Continue after successful writes and after per-item errors.
|
|
@@ -568,6 +675,11 @@ often consists of cheap close-out reconciliation that should drain in one cron p
|
|
|
568
675
|
Report outcomes in these buckets:
|
|
569
676
|
|
|
570
677
|
- `resumed` — stalled in-progress work re-dispatched in place.
|
|
678
|
+
- `resynced` — a stalled build whose PR was merely behind its base, re-synced via
|
|
679
|
+
`gh pr update-branch` so the already-enabled auto-merge can land; the item stays `claimed` for a
|
|
680
|
+
later cycle to confirm the merge and transition.
|
|
681
|
+
- `recovered` — a stalled build whose PR had already merged, advanced by applying the env-resolved
|
|
682
|
+
`claimed → done` transition build-intake never got to (no re-dispatch).
|
|
571
683
|
- `unblocked` — blocker cleared (or answers resolved); re-dispatched or transitioned to
|
|
572
684
|
`ticketed`.
|
|
573
685
|
- `closed_out` — terminal-labeled items whose native open/active state was closed, completed,
|
|
@@ -606,6 +718,10 @@ stuck work accumulates), or interleaved on a longer cadence.
|
|
|
606
718
|
child work is terminal.
|
|
607
719
|
- Apply build `done` ONLY via the env-resolution rules, and trigger native closure only at the
|
|
608
720
|
true terminal `done` value (`leaf-only-lifecycle`).
|
|
721
|
+
- A `blocked` build item's blocker may be a dependency, a validation/quality-gate self-block (no
|
|
722
|
+
dependency — re-check by re-running `lisa:tracker-validate` against current content), or an
|
|
723
|
+
ambiguity. Re-check every class present; do not treat "no `is blocked by` links" as "nothing to
|
|
724
|
+
do."
|
|
609
725
|
- Never re-dispatch a `blocked` build item unless every parsed blocker is cleared (conservative
|
|
610
726
|
dependency clearing).
|
|
611
727
|
- Repair every materially actionable candidate inside the `max_candidates` cap; default cap is 100.
|
|
@@ -264,24 +264,30 @@ Invoke `lisa:github-agent` (the per-issue lifecycle agent) with the issue ref. `
|
|
|
264
264
|
|
|
265
265
|
Wait for `lisa:github-agent` to return. Capture its outcome:
|
|
266
266
|
|
|
267
|
-
- **Success** — PR
|
|
267
|
+
- **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.
|
|
268
268
|
- **Blocked by github-verify pre-flight gate** — `lisa:github-agent` itself 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.
|
|
269
269
|
- **Blocked by ticket-triage ambiguities** — `lisa:github-agent` posts findings and stops. The issue stays in `$CLAIMED`. Surface to human; do not auto-relabel. Record under "Errors".
|
|
270
270
|
- **Errored** — exception, missing config, etc. Leave the issue in `$CLAIMED` for human investigation. Record under "Errors".
|
|
271
271
|
|
|
272
|
-
#### 3d. Transition to $DONE (only
|
|
272
|
+
#### 3d. Transition to $DONE (only after the PR is merged)
|
|
273
|
+
|
|
274
|
+
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.
|
|
273
275
|
|
|
274
276
|
If `lisa:github-agent` returned Success:
|
|
275
277
|
|
|
276
|
-
1.
|
|
277
|
-
|
|
278
|
+
1. **Confirm the PR merged.** Read the live state of the issue's PR — `gh pr view <pr> --json state,mergedAt,mergeStateStatus,url`:
|
|
279
|
+
- **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.
|
|
280
|
+
- **Open / not yet merged** → do **not** transition. The build is sound but the change has reached no environment yet. Record the issue 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 merged, applies this same env transition. Do **not** comment "Build complete" or close anything.
|
|
281
|
+
- **Closed without merging** → record an Error (the PR was abandoned unmerged); leave the issue in `$CLAIMED`.
|
|
282
|
+
2. Resolve `$DONE` for this issue's PR base branch using the Workflow resolution algorithm above. If env can't be resolved and `done` is env-keyed, record an Error and skip this transition — never guess.
|
|
283
|
+
3. Determine whether `$DONE` is the true terminal done value per the `leaf-only-lifecycle` rule's Terminal native closure section:
|
|
278
284
|
- If `github.labels.build.done` is a string, that string is terminal.
|
|
279
285
|
- If `github.labels.build.done` is an object, only the production/final environment value is terminal (default: `status:done`). Intermediate env values such as `status:on-dev` and `status:on-stg` are not terminal and must stay open.
|
|
280
286
|
- If the project uses a different final environment name, resolve it from the configured deployment topology; if ambiguous, record an Error and do not close.
|
|
281
287
|
|
|
282
288
|
```bash
|
|
283
289
|
gh issue edit <number> --repo <org>/<repo> --remove-label "$CLAIMED" --add-label "$DONE"
|
|
284
|
-
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Build complete. PR <URL
|
|
290
|
+
gh issue comment <number> --repo <org>/<repo> --body "[claude-build-intake] Build complete. PR <URL> merged. Transitioned to $DONE."
|
|
285
291
|
```
|
|
286
292
|
|
|
287
293
|
If `$DONE` is terminal, immediately close the native GitHub issue:
|
|
@@ -308,8 +314,10 @@ Cycle started: <ISO timestamp>
|
|
|
308
314
|
Cycle completed: <ISO timestamp>
|
|
309
315
|
|
|
310
316
|
Issues processed: <n>
|
|
311
|
-
- $DONE (build complete, PR
|
|
317
|
+
- $DONE (build complete, PR merged): <n>
|
|
312
318
|
- <org>/<repo>#<number> <title> → PR <URL>
|
|
319
|
+
- PR open — awaiting merge (left in $CLAIMED for repair-intake): <n>
|
|
320
|
+
- <org>/<repo>#<number> <title> → PR <URL> (mergeStateStatus: <state>)
|
|
313
321
|
- Repaired (container — leaf-only-lifecycle): <n>
|
|
314
322
|
- <org>/<repo>#<number> <title> — build-ready on a parent/container; moved $READY → $CLAIMED without invoking lisa:github-agent; lifecycle-repair comment posted
|
|
315
323
|
- Skipped (active blockers): <n>
|