@codyswann/lisa 2.126.0 → 2.126.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/package.json +1 -1
  2. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  3. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  4. package/plugins/lisa/commands/repair-intake.md +1 -1
  5. package/plugins/lisa/rules/eager/leaf-only-lifecycle.md +5 -3
  6. package/plugins/lisa/rules/reference/leaf-only-lifecycle.md +13 -8
  7. package/plugins/lisa/skills/github-sync/SKILL.md +7 -6
  8. package/plugins/lisa/skills/jira-sync/SKILL.md +7 -6
  9. package/plugins/lisa/skills/linear-sync/SKILL.md +6 -5
  10. package/plugins/lisa/skills/repair-intake/SKILL.md +63 -29
  11. package/plugins/lisa/skills/tracker-sync/SKILL.md +5 -4
  12. package/plugins/lisa-agy/commands/repair-intake.md +1 -1
  13. package/plugins/lisa-agy/plugin.json +1 -1
  14. package/plugins/lisa-agy/skills/github-sync/SKILL.md +7 -6
  15. package/plugins/lisa-agy/skills/jira-sync/SKILL.md +7 -6
  16. package/plugins/lisa-agy/skills/linear-sync/SKILL.md +6 -5
  17. package/plugins/lisa-agy/skills/repair-intake/SKILL.md +63 -29
  18. package/plugins/lisa-agy/skills/tracker-sync/SKILL.md +5 -4
  19. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  22. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-copilot/commands/repair-intake.md +1 -1
  26. package/plugins/lisa-copilot/rules/eager/leaf-only-lifecycle.md +5 -3
  27. package/plugins/lisa-copilot/rules/reference/leaf-only-lifecycle.md +13 -8
  28. package/plugins/lisa-copilot/skills/github-sync/SKILL.md +7 -6
  29. package/plugins/lisa-copilot/skills/jira-sync/SKILL.md +7 -6
  30. package/plugins/lisa-copilot/skills/linear-sync/SKILL.md +6 -5
  31. package/plugins/lisa-copilot/skills/repair-intake/SKILL.md +63 -29
  32. package/plugins/lisa-copilot/skills/tracker-sync/SKILL.md +5 -4
  33. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-cursor/commands/repair-intake.md +1 -1
  35. package/plugins/lisa-cursor/rules/leaf-only-lifecycle-reference.mdc +13 -8
  36. package/plugins/lisa-cursor/rules/leaf-only-lifecycle.mdc +5 -3
  37. package/plugins/lisa-cursor/skills/github-sync/SKILL.md +7 -6
  38. package/plugins/lisa-cursor/skills/jira-sync/SKILL.md +7 -6
  39. package/plugins/lisa-cursor/skills/linear-sync/SKILL.md +6 -5
  40. package/plugins/lisa-cursor/skills/repair-intake/SKILL.md +63 -29
  41. package/plugins/lisa-cursor/skills/tracker-sync/SKILL.md +5 -4
  42. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-expo-agy/plugin.json +1 -1
  45. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  49. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  50. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  54. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  55. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  58. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  59. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  60. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-rails-agy/plugin.json +1 -1
  65. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  69. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  70. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  72. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  74. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  75. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  77. package/plugins/src/base/commands/repair-intake.md +1 -1
  78. package/plugins/src/base/rules/eager/leaf-only-lifecycle.md +5 -3
  79. package/plugins/src/base/rules/reference/leaf-only-lifecycle.md +13 -8
  80. package/plugins/src/base/skills/github-sync/SKILL.md +7 -6
  81. package/plugins/src/base/skills/jira-sync/SKILL.md +7 -6
  82. package/plugins/src/base/skills/linear-sync/SKILL.md +6 -5
  83. package/plugins/src/base/skills/repair-intake/SKILL.md +63 -29
  84. package/plugins/src/base/skills/tracker-sync/SKILL.md +5 -4
  85. package/scripts/plugin-routing-validate.mjs +68 -0
@@ -28,19 +28,20 @@ If `$ARGUMENTS` is empty, all vendor skills auto-detect a ticket reference from
28
28
 
29
29
  When the caller passes `--rollup` after the milestone, the dispatch target additionally **derives the parent/container's lifecycle state from its children** instead of acting on the work item directly. This is the vendor-neutral implementation of the **Parent status rollup (the state machine)** section of the `leaf-only-lifecycle` rule — cite that rule, do not restate the policy here. The shim is dispatch only; the rollup mechanics live in the vendor sync skill (`lisa:github-sync`, `lisa:jira-sync`, `lisa:linear-sync`), which resolves child membership via its `*-read-*` skill and evaluates the state machine below.
30
30
 
31
- The state machine (first match wins, evaluated over the **required** leaves only):
31
+ The state machine (first match wins, evaluated over the **required** leaves only, on the env ladder `in-progress < dev < staging < production` — the ordered keys of the project's env-keyed `done` map):
32
32
 
33
33
  | If among the required leaves… | …the parent rolls up to | Role |
34
34
  |---|---|---|
35
35
  | any leaf is **blocked** | blocked / attention-needed | `blocked` |
36
- | else any leaf is **in progress** (claimed or in review) | active / in-progress | `claimed` |
37
- | else **all** required leaves are **terminal** | the configured rollup terminal | `done` (or `review` where supported) |
36
+ | else **every** required leaf has shipped to some env (each at a `done`-map value) | the **least-advanced** env among them | `done[min-env]` (terminal `done` at production) |
37
+ | else any leaf has **started** (claimed or in review, or shipped while a sibling has not) | active / in-progress | `claimed` (or `review` where supported) |
38
38
  | else (leaves exist, none started) | unchanged | — |
39
39
 
40
40
  - **Blocked dominates** — one blocked leaf surfaces blocked on the parent even while others progress.
41
+ - **Least-advanced env wins** — a parent reaches an env only once all required leaves have reached at least that env (all `On Stg` → `On Stg`; mixed dev/staging → the dev value). Native terminal closure fires only at the production `done`, never at an intermediate env.
41
42
  - **The parent never carries `ready`** — `ready` is a human "claim this leaf" signal; rollup only moves a parent between non-ready container states.
42
43
  - **Rollup is recursive** — an Epic rolls up from its Stories, each of which rolls up from its own leaves. Evaluate bottom-up.
43
- - **The terminal is the configured env-keyed `done`** — multi-env projects roll up to whichever `done` value matches the env their leaves shipped to (see `config-resolution` "Env-keyed `done`"). **Single-environment collapse (this repo):** `deploy.branches` declares only `production: main`, so `done` is a single value and the GitHub build lifecycle collapses to `ready → claimed (in-progress) → done`; the rollup terminal is simply `done` (or the PRD-side `ticketed` for PRD containers), with **no** dev/staging promotion hops and **no** env-keyed multi-entry chain to resolve.
44
+ - **The env rungs are the configured env-keyed `done`** — multi-env projects roll up to whichever `done` value (including intermediate `On Dev`/`On Stg`) their leaves have collectively reached (see `config-resolution` "Env-keyed `done`"). **Single-environment collapse (this repo):** `deploy.branches` declares only `production: main`, so `done` is a single value, the only env rung is production, and the GitHub build lifecycle collapses to `ready → claimed (in-progress) → done`; the rollup terminal is simply `done` (or the PRD-side `ticketed` for PRD containers), with **no** dev/staging promotion hops and **no** env-keyed multi-entry chain to resolve.
44
45
 
45
46
  **Safe-by-default when not yet supported.** A vendor sync path that has not implemented native rollup MUST be a documented no-op that surfaces the derived state as a suggestion/comment rather than guessing a transition — never an unsafe default. Without `--rollup`, the sync skills behave exactly as before (milestone comment on the work item; no parent derivation).
46
47
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "2.126.0",
3
+ "version": "2.126.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Repair counterpart to /lisa:intake. Vendor-agnostic batch scanner that finds stuck or half-closed work — items left in `blocked`, stalled in an in-progress role (build `claimed`, PRD `in_review`), terminal-labeled items still natively open, and rollups whose children are all terminal — across the same queues /lisa:intake serves (Notion / Confluence / Linear / GitHub PRDs; JIRA / GitHub / Linear build issues). Repairs every materially actionable candidate inside the `max_candidates` cap: resumes stalled in-progress work in place — but for a stalled build it first diagnoses the PR/deploy state and, if the PR cannot merge (conflict, rebase, failing checks, unaddressed CodeRabbit/changes-requested) or a deploy failed, files a build-ready fix ticket and moves the item to `blocked` (blocked by it) instead of re-dispatching — re-validates blocked PRDs, re-dispatches blocked build items whose blockers have cleared, performs terminal native closure, and closes out completed rollups. Cron-safe and bounded; default GitHub intake_mode is both and default max_candidates is 100."
2
+ description: "Repair counterpart to /lisa:intake. Vendor-agnostic batch scanner that finds stuck or half-closed work — items left in `blocked`, stalled in an in-progress role (build `claimed`, PRD `in_review`), terminal-labeled items still natively open, and rollups whose children are all terminal — across the same queues /lisa:intake serves (Notion / Confluence / Linear / GitHub PRDs; JIRA / GitHub / Linear build issues). Repairs every materially actionable candidate inside the `max_candidates` cap: resumes stalled in-progress work in place — but for a stalled build it first diagnoses the PR/deploy state and, if the PR cannot merge (conflict, rebase, failing checks, unaddressed CodeRabbit/changes-requested) or a deploy failed, files a build-ready fix ticket and moves the item to `blocked` (blocked by it) instead of re-dispatching — re-validates blocked PRDs, re-dispatches blocked build items whose blockers have cleared, performs terminal native closure, reconciles parent rollups to their derived state (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 completed rollups. Cron-safe and bounded; default GitHub intake_mode is both and default max_candidates is 100."
3
3
  argument-hint: "<Notion-PRD-database-URL | Confluence-space-URL | Confluence-parent-page-URL | Linear-workspace-URL | Linear-team-URL | GitHub-repo-URL | org/repo | JIRA-project-key | JQL-filter> [intake_mode=prd|build|both] [stale_after=2h] [max_candidates=100] [force=true]"
4
4
  ---
5
5
 
@@ -19,12 +19,14 @@ A container *type* with no children is structurally a leaf — and may be build-
19
19
 
20
20
  ## Parent state rollup (priority order, first match wins)
21
21
 
22
+ Evaluate over the env ladder `in-progress < dev < staging < production` (the ordered keys of the project's env-keyed `done` map; single-env projects have only the production rung):
23
+
22
24
  1. Any leaf is **blocked** → parent rolls up to **blocked / attention-needed**.
23
- 2. Else any leaf is **claimed or in review** → parent is **in-progress**.
24
- 3. Else all required leaves are **terminal (`done`)** parent reaches the configured rollup terminal (env-keyed `done`).
25
+ 2. Else **every** required leaf has shipped to some env → parent rolls up to the **least-advanced** env among them (all `On Stg` → `On Stg`; mixed `On Dev`+`On Stg` → `On Dev`; all production → terminal `done`).
26
+ 3. Else any leaf has **started** (claimed/in review, or shipped while a sibling has not) → parent is **in-progress** (`claimed`).
25
27
  4. Else (leaves exist but none started) → parent unchanged.
26
28
 
27
- **Blocked dominates.** Optional/won't-do children do not hold a parent open. Rollup is recursive — bottom-up. The parent never carries `ready`.
29
+ **Blocked dominates.** A parent reaches an env only once all required leaves have reached at least that env. Intermediate-env rollup (`On Dev`/`On Stg`) happens, but native closure fires only at production `done`. Optional/won't-do children do not hold a parent open. Rollup is recursive — bottom-up. The parent never carries `ready`; a container found in `ready` is reconciled by rolling it up from its children.
28
30
 
29
31
  ## Terminal native closure
30
32
 
@@ -60,26 +60,31 @@ So the exception is narrow: childlessness *enables* build-ready only for types t
60
60
 
61
61
  A parent/container never sets its own lifecycle state; it **derives** it from the roll-up of its children's states. Rollup is evaluated whenever a child transitions (or when intake observes the child set). Using the canonical build-lifecycle roles from `config-resolution` (`ready`, `claimed`, `review`, `blocked`, `done`):
62
62
 
63
- Evaluate the children in priority order and take the **first** match:
63
+ Evaluate over the **env ladder** `in-progress < dev < staging < production` — the ordered keys of the project's env-keyed `done` map, with `claimed`/`review` as the rung below the first env (a single-environment project has only the `production` rung). Take the **first** match:
64
64
 
65
65
  | If among the required leaves… | …the parent rolls up to | Role |
66
66
  |---|---|---|
67
67
  | any leaf is **blocked** | blocked / attention-needed | `blocked` |
68
- | else any leaf is **in progress** (claimed or in review) | active / in-progress | `claimed` |
69
- | else **all** required leaves are **terminal** (`done`) | the configured rollup terminal state | `done` (or `review` where supported — see below) |
68
+ | else **every** required leaf has shipped to some env (each is at a `done`-map value) | the **least-advanced** env among them on the ladder | env-keyed `done[min-env]` (terminal `done` when that env is production) |
69
+ | else any leaf has **started** (claimed / in review, or shipped to some env while a sibling has not) | active / in-progress | `claimed` (or `review` where supported — see below) |
70
70
  | else (leaves exist but none started) | unchanged (parent stays in its non-ready container state) | — |
71
71
 
72
+ The middle two rungs are the same idea seen at two resolutions: a parent reaches an env only once **all** its required leaves have reached **at least** that env. So all leaves at `On Stg` → parent `On Stg`; a mix of `On Dev` and `On Stg` → parent `On Dev` (the set as a whole has only fully reached dev); any leaf still `claimed`/`review` (not yet shipped anywhere) holds the parent at `claimed`. In a single-environment project the only env rung is production, so this collapses to the familiar "all leaves `done` → parent `done`, else `claimed`."
73
+
72
74
  Notes:
73
75
 
74
76
  - **Blocked dominates.** A single blocked leaf surfaces blocked/attention on the parent even if other leaves are progressing, so a human sees the parent needs attention.
75
- - **"Required" leaves.** Optional or won't-do children do not hold a parent open; only the leaves that must ship for the parent to be complete are counted toward the all-terminal check.
76
- - **Rollup is recursive.** An Epic rolls up from its Stories, each of which rolls up from its own leaves. Evaluate bottom-up: a Story reaches `done` only when its leaves are all terminal; an Epic reaches `done` only when its Stories are all `done`.
77
+ - **"Required" leaves.** Optional or won't-do children do not hold a parent open; only the leaves that must ship for the parent to be complete are counted toward the env-rollup check.
78
+ - **Least-advanced env wins.** The parent reflects the env the whole required set has collectively reached never an env ahead of its laggard leaf. Native closure (below) fires only when the resolved env is the production/terminal value, never at an intermediate env (`On Dev`/`On Stg`).
79
+ - **Rollup is recursive.** An Epic rolls up from its Stories, each of which rolls up from its own leaves. Evaluate bottom-up: a Story reaches an env only when its leaves have all reached at least that env; an Epic reaches it only when its Stories have.
77
80
  - **Vendor support varies.** Apply the rollup state the vendor can express. Where a vendor has no native intermediate state, use the nearest configured role or a metadata/comment signal rather than forcing a non-existent status (PRD #522 non-goal: vendors need not expose identical states).
78
- - **The parent never carries `ready`.** `ready` is a *human* "this is buildable, claim it" signal and only ever lives on leaves. Rollup moves a parent between non-ready container states (in-progress / blocked / terminal); it never sets the parent to `ready`.
81
+ - **The parent never carries `ready`.** `ready` is a *human* "this is buildable, claim it" signal and only ever lives on leaves. Rollup moves a parent between non-ready container states (in-progress / per-env / blocked / terminal); it never sets the parent to `ready`. A container found carrying `ready` is a leaf-only-invariant violation — recompute its rolled state from its children and apply that (see `repair-intake`).
82
+
83
+ ### The rollup env states are the configured "done" map — multi-env capable
79
84
 
80
- ### The rollup terminal state is the configured "done" — multi-env capable
85
+ The env rungs are whatever the project configures for `done` — which is **env-keyed** (`config-resolution` "Env-keyed `done`"): a `done` map keyed by environment (`dev`, `staging`, `production`), each leaf's env resolved from its merged PR's base branch. This rule does **not** hardcode a `dev → staging → prod` promotion chain as required that is a project-specific deploy topology; the ladder is simply the ordered keys of the project's `done` map. A downstream project with dev/staging/prod environments rolls a parent up to the least-advanced env value its required leaves have collectively reached (an intermediate-env parent state, e.g. `On Stg`), and only to the production `done` value once every required leaf is at production. The rule stays generic and multi-env capable.
81
86
 
82
- The terminal rollup state is whatever the project configures for `done` which is **env-keyed** (`config-resolution` "Env-keyed `done`"): a `done` map keyed by environment (`dev`, `staging`, `production`), resolved from the merged PR's base branch. This rule does **not** hardcode a `dev → staging → prod` promotion chain as required — that is a project-specific deploy topology. A downstream project with dev/staging/prod environments rolls a parent up to whichever terminal `done` value matches the environment its leaves shipped to. The rule stays generic and multi-env capable.
87
+ Intermediate-env rollup and terminal native closure are distinct: a parent **rolls up to** an intermediate env (`On Dev`/`On Stg`) as its required leaves reach it, but native closure (next section) fires **only** at the production/terminal `done` value. A parent sitting at `On Stg` is correctly rolled up *and* still open.
83
88
 
84
89
  **Single-environment collapse (this repo).** Lisa's own deploy has only `main`/`production` (no dev/staging), so `done` is a single value, not a map. For GitHub, the build lifecycle collapses to one chain: `ready → claimed (in-progress) → done`. The rollup terminal state is simply `done`. This is the *collapsed* case of the generic rule, not a different rule — projects with more environments keep the env-keyed map.
85
90
 
@@ -82,21 +82,22 @@ gh api graphql -f query='
82
82
 
83
83
  If the `subIssues` field is unavailable (older GHES), fall back to body parentage exactly as `lisa:github-read-issue` does. If the issue has **no** children it is a leaf, not a parent — rollup is N/A; behave as a normal milestone sync.
84
84
 
85
- **Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; the GitHub label map is `status:blocked`, `status:in-progress`, `status:done`):
85
+ **Evaluate the required children over the env ladder `in-progress < dev < staging < production` (the ordered keys of the GitHub env-keyed `done` map, e.g. `status:on-dev < status:on-stg < status:done`) and take the first match** (canonical roles from `config-resolution`; the GitHub label map is `status:blocked`, `status:in-progress`, env-keyed `done`):
86
86
 
87
87
  | If among the required child leaves… | Derived parent role | GitHub label |
88
88
  |---|---|---|
89
89
  | any child carries `status:blocked` (or is otherwise blocked) | `blocked` | `status:blocked` |
90
- | else any child carries `status:in-progress` | `claimed` | `status:in-progress` |
91
- | else **all** required children are terminal (closed / `status:done`) | `done` | the configured terminal `done` label |
90
+ | else **every** required child has shipped to some env (each at a `done`-map label, e.g. `status:on-dev`/`status:on-stg`/`status:done`) | `done[min-env]` | the **least-advanced** env label among them (all `status:on-stg` → `status:on-stg`; mixed dev+staging → `status:on-dev`; all production → `status:done`) |
91
+ | else any child has **started** (`status:in-progress`, or shipped to an env while a sibling has not) | `claimed` | `status:in-progress` |
92
92
  | else (children exist, none started) | — | unchanged — parent keeps its non-ready container label |
93
93
 
94
94
  - **Blocked dominates** — a single blocked child surfaces `status:blocked` on the parent even while siblings progress, so a human sees the parent needs attention.
95
- - **"Required" children only** — a child labelled won't-do / optional does not hold the parent open; only leaves that must ship count toward the all-terminal check.
96
- - **Recursive** — a parent reaches `done` only when its children are all terminal; an Epic reaches `done` only when its Stories have themselves rolled up to `done`. Evaluate bottom-up.
95
+ - **Least-advanced env wins** — the parent reaches an env only when every required child has reached at least that env; it never sits ahead of its laggard child. Native closure (`gh issue close --reason completed`) fires only when the resolved env is the production `status:done`, never at `status:on-dev`/`status:on-stg`.
96
+ - **"Required" children only** — a child labelled won't-do / optional does not hold the parent open; only leaves that must ship count toward the env-rollup check.
97
+ - **Recursive** — a parent reaches an env only when its children have all reached at least that env; an Epic reaches it only when its Stories have themselves rolled up to it. Evaluate bottom-up.
97
98
  - **Never set the parent to `status:ready`** — `ready` is leaf-only (the human "claim this" signal). Rollup only moves the parent between non-ready container labels.
98
99
 
99
- **Single-environment collapse (this repo).** `.lisa.config.json` `deploy.branches` declares only `production: main`, so the terminal `done` resolves to the single label `status:done` — there is no `status:on-dev` / `status:on-stg` and **no dev → staging → prod promotion chain**. Resolve the terminal via the env-keyed `done` logic in `config-resolution`, but in the single-environment case it collapses to the one `status:done` value; the rollup never attempts to resolve a dev or staging `done`. Projects that DO have multiple environments keep the env-keyed map and roll the parent up to whichever `done` matches the environment its leaves shipped to.
100
+ **Single-environment collapse (this repo).** `.lisa.config.json` `deploy.branches` declares only `production: main`, so the env-keyed `done` resolves to the single label `status:done` — there is no `status:on-dev` / `status:on-stg` and **no dev → staging → prod promotion chain**. Resolve the env rungs via the env-keyed `done` logic in `config-resolution`, but in the single-environment case the only rung is production and it collapses to the one `status:done` value; the rollup never attempts to resolve a dev or staging `done`. Projects that DO have multiple environments keep the env-keyed map and roll the parent up to whichever `done` (including intermediate `status:on-dev`/`status:on-stg`) its leaves have collectively reached.
100
101
 
101
102
  **Apply the derived label** (only when it differs from the parent's current `status:*`): remove the parent's existing `status:*` label and add the derived one, keeping exactly one `status:*` label so the build-queue invariant holds. Post an idempotent `[claude-sync] rollup` comment naming the derived state and the child tally (e.g. `3/4 leaves terminal, 1 blocked → status:blocked`); skip the comment if an identical one is already the most recent rollup comment.
102
103
 
@@ -64,22 +64,23 @@ When invoked with `--rollup`, this skill **derives a parent/container ticket's s
64
64
 
65
65
  **Resolve the child set the same way `lisa:jira-read-ticket` does** — the native Epic → Story → Sub-task hierarchy (Epic link / parent field for Stories, the subtask relationship for Sub-tasks), each with its current status. Fetch via `lisa:atlassian-access` (`operation: read-ticket` / `search-issues` with the parent's `"Epic Link" = <KEY>` or `parent = <KEY>` JQL). If the ticket has **no** children it is a leaf — rollup is N/A; behave as a normal milestone sync.
66
66
 
67
- **Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; the JIRA status map defaults to `Blocked`, `In Progress`, `Code Review`, env-keyed `done`):
67
+ **Evaluate the required children over the env ladder `in-progress < dev < staging < production` (the ordered keys of the JIRA env-keyed `done` map, e.g. `On Dev < On Stg < Done`) and take the first match** (canonical roles from `config-resolution`; the JIRA status map defaults to `Blocked`, `In Progress`, `Code Review`, env-keyed `done`):
68
68
 
69
69
  | If among the required child leaves… | Derived parent role | JIRA status |
70
70
  |---|---|---|
71
71
  | any child is **blocked** | `blocked` | `Blocked` |
72
- | else any child is **in progress** (`In Progress` or `Code Review`) | `claimed` | `In Progress` |
73
- | else **all** required children are terminal (`Done`) | `done` | the configured terminal `done` status |
72
+ | else **every** required child has shipped to some env (each at a `done`-map value, e.g. `On Dev`/`On Stg`/`Done`) | `done[min-env]` | the **least-advanced** env status among them (all `On Stg` → `On Stg`; mixed `On Dev`+`On Stg` → `On Dev`; all production → `Done`) |
73
+ | else any child has **started** (`In Progress` / `Code Review`, or shipped to an env while a sibling has not) | `claimed` | `In Progress` |
74
74
  | else (children exist, none started) | — | unchanged — parent keeps its non-ready container status |
75
75
 
76
76
  - **Blocked dominates** — a single blocked child surfaces `Blocked` on the parent even while siblings progress.
77
+ - **Least-advanced env wins** — the parent reaches an env only when every required child has reached at least that env; it never sits ahead of its laggard child. Apply native terminal resolution (the `leaf-only-lifecycle` Terminal native closure) only when the resolved env is the production `Done`, never at `On Dev`/`On Stg`.
77
78
  - **"Required" children only** — won't-do / optional children do not hold the parent open.
78
- - **Recursive** — an Epic reaches `Done` only when its Stories have themselves rolled up to `Done`; a Story reaches `Done` only when its Sub-tasks are all terminal. Evaluate bottom-up.
79
+ - **Recursive** — an Epic reaches an env only when its Stories have themselves rolled up to at least that env; a Story reaches it only when its Sub-tasks have. Evaluate bottom-up.
79
80
  - **Never set the parent to the build-ready status** — `ready` is leaf-only. Rollup only moves the parent between non-ready container statuses.
80
- - **`review` is optional for JIRA** (`config-resolution`) — a project that omits `Code Review` keeps the parent in `In Progress` until terminal; skip the intermediate rollup hop rather than forcing a non-existent status (a `leaf-only-lifecycle` "vendor support varies" note).
81
+ - **`review` is optional for JIRA** (`config-resolution`) — a project that omits `Code Review` keeps the parent in `In Progress` until it shifts to an env; skip the intermediate review hop rather than forcing a non-existent status (a `leaf-only-lifecycle` "vendor support varies" note).
81
82
 
82
- **Single-environment collapse (this repo).** The terminal `done` resolves via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to a single status and the lifecycle is `Ready → In Progress → Code Review → Done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map.
83
+ **Single-environment collapse (this repo).** The env rungs resolve via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to a single status, the only env rung is production, and the lifecycle is `Ready → In Progress → Code Review → Done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map and roll a parent up to intermediate env statuses (`On Dev`/`On Stg`).
83
84
 
84
85
  **Apply the derived status** (only when it differs from the parent's current status) via `lisa:atlassian-access` `operation: transition`, and post an idempotent rollup comment naming the derived state and the child tally. **Safe default:** if the derived terminal cannot be resolved (ambiguous required-set or unresolvable env `done`), do not guess — post the derived suggestion as a comment and leave the parent's status untouched.
85
86
 
@@ -87,21 +87,22 @@ When the caller passes `--rollup`, this skill **derives a parent/container's `st
87
87
 
88
88
  **Resolve the child set the same way `lisa:linear-read-issue` does** — `mcp__linear-server__list_issues({project: <id>})` for a Project's Issues, or `mcp__linear-server__get_issue` per child for an Issue's sub-Issues (via `parentId`). Capture each child's `status:*` label. If the item has **no** children it is a leaf — rollup is N/A; behave as a normal milestone sync.
89
89
 
90
- **Evaluate the required children in priority order and take the first match** (canonical roles from `config-resolution`; Linear label map is `status:blocked`, `status:in-progress`, `status:code-review`, `status:done`):
90
+ **Evaluate the required children over the env ladder `in-progress < dev < staging < production` (the ordered keys of the Linear env-keyed `done` map, e.g. `status:on-dev < status:on-stg < status:done`) and take the first match** (canonical roles from `config-resolution`; Linear label map is `status:blocked`, `status:in-progress`, `status:code-review`, env-keyed `done`):
91
91
 
92
92
  | If among the required child leaves… | Derived parent role | Linear label |
93
93
  |---|---|---|
94
94
  | any child carries `status:blocked` | `blocked` | `status:blocked` |
95
- | else any child carries `status:in-progress` **or** `status:code-review` | `claimed` | `status:in-progress` |
96
- | else **all** required children carry `status:done` | `done` | the configured terminal `done` label |
95
+ | else **every** required child has shipped to some env (each at a `done`-map label, e.g. `status:on-dev`/`status:on-stg`/`status:done`) | `done[min-env]` | the **least-advanced** env label among them (all `status:on-stg` `status:on-stg`; mixed dev+staging → `status:on-dev`; all production → `status:done`) |
96
+ | else any child has **started** (`status:in-progress` / `status:code-review`, or shipped to an env while a sibling has not) | `claimed` | `status:in-progress` |
97
97
  | else (children exist, none started) | — | unchanged — parent keeps its non-ready container label |
98
98
 
99
99
  - **Blocked dominates** — one blocked child surfaces `status:blocked` on the parent even while siblings progress.
100
+ - **Least-advanced env wins** — the parent reaches an env only when every required child has reached at least that env; it never sits ahead of its laggard child. Native completion (moving the workflow `state` to Done) fires only when the resolved env is the production `status:done`, never at `status:on-dev`/`status:on-stg`.
100
101
  - **"Required" children only** — won't-do / optional (e.g. `Canceled`) children do not hold the parent open.
101
- - **Recursive** — a Project reaches `status:done` only when its Issues have themselves rolled up to `status:done`. Evaluate bottom-up.
102
+ - **Recursive** — a Project reaches an env only when its Issues have themselves rolled up to at least that env. Evaluate bottom-up.
102
103
  - **Never set the parent to `status:ready`** — `ready` is leaf-only. Rollup only moves the parent between non-ready container labels.
103
104
 
104
- **Single-environment collapse (this repo).** The terminal `done` resolves via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to the single `status:done` label and the lifecycle is `status:ready → status:in-progress → status:code-review → status:done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map.
105
+ **Single-environment collapse (this repo).** The env rungs resolve via the env-keyed `done` logic in `config-resolution`. In this repo `deploy.branches` declares only `production: main`, so `done` collapses to the single `status:done` label, the only env rung is production, and the lifecycle is `status:ready → status:in-progress → status:code-review → status:done` with **no** dev/staging promotion hops; the rollup never resolves a dev or staging `done`. Multi-environment projects keep the env-keyed map and roll a parent up to intermediate env labels (`status:on-dev`/`status:on-stg`).
105
106
 
106
107
  **Apply the derived label** via `mcp__linear-server__save_issue` (Project or Issue), removing the parent's existing `status:*` and adding the derived one so exactly one `status:*` label remains. Post an idempotent rollup comment naming the derived state and the child tally. The native Linear `state` is **not** auto-transitioned — only the `status:*` label, mirroring the `--update-label` rule. **Safe default:** if the derived terminal cannot be resolved (ambiguous required-set or unresolvable env `done`), do not guess — post the derived suggestion as a comment and leave the parent's label untouched.
107
108