@codyswann/lisa 4.86.1 → 4.87.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  2. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  3. package/dist/core/upstream-evidence-manifest.js +26 -23
  4. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  5. package/package.json +4 -4
  6. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  7. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  8. package/plugins/lisa/.codex-plugin/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  9. package/plugins/lisa/.codex-plugin/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  10. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  11. package/plugins/lisa/.codex-plugin/skills/lisa-github-to-tracker/SKILL.md +5 -0
  12. package/plugins/lisa/.codex-plugin/skills/lisa-github-validate-issue/SKILL.md +2 -0
  13. package/plugins/lisa/.codex-plugin/skills/lisa-implement/SKILL.md +2 -0
  14. package/plugins/lisa/.codex-plugin/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  15. package/plugins/lisa/.codex-plugin/skills/lisa-learnings-audit/SKILL.md +9 -0
  16. package/plugins/lisa/.codex-plugin/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  17. package/plugins/lisa/.codex-plugin/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  18. package/plugins/lisa/.codex-plugin/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  19. package/plugins/lisa/.codex-plugin/skills/lisa-persist-learning/SKILL.md +27 -8
  20. package/plugins/lisa/.codex-plugin/skills/lisa-plan/SKILL.md +2 -0
  21. package/plugins/lisa/.codex-plugin/skills/lisa-pull-request-review/SKILL.md +8 -0
  22. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/SKILL.md +30 -5
  23. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  24. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  25. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  26. package/plugins/lisa/.codex-plugin/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  27. package/plugins/lisa/.codex-plugin/skills/lisa-task-decomposition/SKILL.md +18 -0
  28. package/plugins/lisa/agents/learning-judge.md +34 -14
  29. package/plugins/lisa/rules/reference/ready-role-filing.md +4 -0
  30. package/plugins/lisa/rules/reference/work-item-definition-of-ready.md +8 -0
  31. package/plugins/lisa/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  32. package/plugins/lisa/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  33. package/plugins/lisa/skills/lisa-delivery-effectiveness/agents/openai.yaml +2 -2
  34. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  35. package/plugins/lisa/skills/lisa-github-to-tracker/SKILL.md +5 -0
  36. package/plugins/lisa/skills/lisa-github-validate-issue/SKILL.md +2 -0
  37. package/plugins/lisa/skills/lisa-implement/SKILL.md +2 -0
  38. package/plugins/lisa/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  39. package/plugins/lisa/skills/lisa-learnings-audit/SKILL.md +9 -0
  40. package/plugins/lisa/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  41. package/plugins/lisa/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  42. package/plugins/lisa/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  43. package/plugins/lisa/skills/lisa-persist-learning/SKILL.md +27 -8
  44. package/plugins/lisa/skills/lisa-plan/SKILL.md +2 -0
  45. package/plugins/lisa/skills/lisa-pull-request-review/SKILL.md +8 -0
  46. package/plugins/lisa/skills/lisa-session-manager/SKILL.md +30 -5
  47. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  48. package/plugins/lisa/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  49. package/plugins/lisa/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  50. package/plugins/lisa/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  51. package/plugins/lisa/skills/lisa-task-decomposition/SKILL.md +18 -0
  52. package/plugins/lisa-agy/agents/learning-judge.md +34 -14
  53. package/plugins/lisa-agy/plugin.json +1 -1
  54. package/plugins/lisa-agy/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  55. package/plugins/lisa-agy/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  56. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  57. package/plugins/lisa-agy/skills/lisa-github-to-tracker/SKILL.md +5 -0
  58. package/plugins/lisa-agy/skills/lisa-github-validate-issue/SKILL.md +2 -0
  59. package/plugins/lisa-agy/skills/lisa-implement/SKILL.md +2 -0
  60. package/plugins/lisa-agy/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  61. package/plugins/lisa-agy/skills/lisa-learnings-audit/SKILL.md +9 -0
  62. package/plugins/lisa-agy/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  63. package/plugins/lisa-agy/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  64. package/plugins/lisa-agy/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  65. package/plugins/lisa-agy/skills/lisa-persist-learning/SKILL.md +27 -8
  66. package/plugins/lisa-agy/skills/lisa-plan/SKILL.md +2 -0
  67. package/plugins/lisa-agy/skills/lisa-pull-request-review/SKILL.md +8 -0
  68. package/plugins/lisa-agy/skills/lisa-session-manager/SKILL.md +30 -5
  69. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  70. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  71. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  72. package/plugins/lisa-agy/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  73. package/plugins/lisa-agy/skills/lisa-task-decomposition/SKILL.md +18 -0
  74. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  76. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  77. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
  81. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-copilot/agents/learning-judge.agent.md +34 -14
  83. package/plugins/lisa-copilot/rules/reference/ready-role-filing.md +4 -0
  84. package/plugins/lisa-copilot/rules/reference/work-item-definition-of-ready.md +8 -0
  85. package/plugins/lisa-copilot/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  86. package/plugins/lisa-copilot/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  87. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  88. package/plugins/lisa-copilot/skills/lisa-github-to-tracker/SKILL.md +5 -0
  89. package/plugins/lisa-copilot/skills/lisa-github-validate-issue/SKILL.md +2 -0
  90. package/plugins/lisa-copilot/skills/lisa-implement/SKILL.md +2 -0
  91. package/plugins/lisa-copilot/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  92. package/plugins/lisa-copilot/skills/lisa-learnings-audit/SKILL.md +9 -0
  93. package/plugins/lisa-copilot/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  94. package/plugins/lisa-copilot/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  95. package/plugins/lisa-copilot/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  96. package/plugins/lisa-copilot/skills/lisa-persist-learning/SKILL.md +27 -8
  97. package/plugins/lisa-copilot/skills/lisa-plan/SKILL.md +2 -0
  98. package/plugins/lisa-copilot/skills/lisa-pull-request-review/SKILL.md +8 -0
  99. package/plugins/lisa-copilot/skills/lisa-session-manager/SKILL.md +30 -5
  100. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  101. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  102. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  103. package/plugins/lisa-copilot/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  104. package/plugins/lisa-copilot/skills/lisa-task-decomposition/SKILL.md +18 -0
  105. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  106. package/plugins/lisa-cursor/agents/learning-judge.md +34 -14
  107. package/plugins/lisa-cursor/rules/ready-role-filing-reference.mdc +4 -0
  108. package/plugins/lisa-cursor/rules/work-item-definition-of-ready-reference.mdc +8 -0
  109. package/plugins/lisa-cursor/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  110. package/plugins/lisa-cursor/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  111. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  112. package/plugins/lisa-cursor/skills/lisa-github-to-tracker/SKILL.md +5 -0
  113. package/plugins/lisa-cursor/skills/lisa-github-validate-issue/SKILL.md +2 -0
  114. package/plugins/lisa-cursor/skills/lisa-implement/SKILL.md +2 -0
  115. package/plugins/lisa-cursor/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  116. package/plugins/lisa-cursor/skills/lisa-learnings-audit/SKILL.md +9 -0
  117. package/plugins/lisa-cursor/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  118. package/plugins/lisa-cursor/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  119. package/plugins/lisa-cursor/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  120. package/plugins/lisa-cursor/skills/lisa-persist-learning/SKILL.md +27 -8
  121. package/plugins/lisa-cursor/skills/lisa-plan/SKILL.md +2 -0
  122. package/plugins/lisa-cursor/skills/lisa-pull-request-review/SKILL.md +8 -0
  123. package/plugins/lisa-cursor/skills/lisa-session-manager/SKILL.md +30 -5
  124. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  125. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  126. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  127. package/plugins/lisa-cursor/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  128. package/plugins/lisa-cursor/skills/lisa-task-decomposition/SKILL.md +18 -0
  129. package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
  130. package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
  131. package/plugins/lisa-devin/agents/learning-judge.md +34 -14
  132. package/plugins/lisa-devin/rules/reference/ready-role-filing.md +4 -0
  133. package/plugins/lisa-devin/rules/reference/work-item-definition-of-ready.md +8 -0
  134. package/plugins/lisa-devin/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  135. package/plugins/lisa-devin/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  136. package/plugins/lisa-devin/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  137. package/plugins/lisa-devin/skills/lisa-github-to-tracker/SKILL.md +5 -0
  138. package/plugins/lisa-devin/skills/lisa-github-validate-issue/SKILL.md +2 -0
  139. package/plugins/lisa-devin/skills/lisa-implement/SKILL.md +2 -0
  140. package/plugins/lisa-devin/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  141. package/plugins/lisa-devin/skills/lisa-learnings-audit/SKILL.md +9 -0
  142. package/plugins/lisa-devin/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  143. package/plugins/lisa-devin/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  144. package/plugins/lisa-devin/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  145. package/plugins/lisa-devin/skills/lisa-persist-learning/SKILL.md +27 -8
  146. package/plugins/lisa-devin/skills/lisa-plan/SKILL.md +2 -0
  147. package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +8 -0
  148. package/plugins/lisa-devin/skills/lisa-session-manager/SKILL.md +30 -5
  149. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  150. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  151. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  152. package/plugins/lisa-devin/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  153. package/plugins/lisa-devin/skills/lisa-task-decomposition/SKILL.md +18 -0
  154. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  155. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  156. package/plugins/lisa-expo-agy/plugin.json +1 -1
  157. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  158. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  159. package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
  160. package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
  161. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  162. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  163. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  164. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  165. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  166. package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
  167. package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
  168. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  169. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  170. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  171. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  172. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  173. package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
  174. package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
  175. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  176. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  177. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  178. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  179. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  180. package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
  181. package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
  182. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  183. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  184. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  185. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  186. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  187. package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
  188. package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
  189. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  190. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  191. package/plugins/lisa-rails-agy/plugin.json +1 -1
  192. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  193. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  194. package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
  195. package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
  196. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  197. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  198. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  199. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  200. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  201. package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
  202. package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
  203. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  204. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  205. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  206. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  207. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  208. package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
  209. package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
  210. package/plugins/src/base/agents/learning-judge.md +34 -14
  211. package/plugins/src/base/rules/reference/ready-role-filing.md +4 -0
  212. package/plugins/src/base/rules/reference/work-item-definition-of-ready.md +8 -0
  213. package/plugins/src/base/skills/lisa-confluence-to-tracker/SKILL.md +5 -0
  214. package/plugins/src/base/skills/lisa-delivery-effectiveness/SKILL.md +7 -3
  215. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
  216. package/plugins/src/base/skills/lisa-github-to-tracker/SKILL.md +5 -0
  217. package/plugins/src/base/skills/lisa-github-validate-issue/SKILL.md +2 -0
  218. package/plugins/src/base/skills/lisa-implement/SKILL.md +2 -0
  219. package/plugins/src/base/skills/lisa-jira-validate-ticket/SKILL.md +2 -0
  220. package/plugins/src/base/skills/lisa-learnings-audit/SKILL.md +9 -0
  221. package/plugins/src/base/skills/lisa-linear-to-tracker/SKILL.md +5 -0
  222. package/plugins/src/base/skills/lisa-linear-validate-issue/SKILL.md +2 -0
  223. package/plugins/src/base/skills/lisa-notion-to-tracker/SKILL.md +5 -0
  224. package/plugins/src/base/skills/lisa-persist-learning/SKILL.md +27 -8
  225. package/plugins/src/base/skills/lisa-plan/SKILL.md +2 -0
  226. package/plugins/src/base/skills/lisa-pull-request-review/SKILL.md +8 -0
  227. package/plugins/src/base/skills/lisa-session-manager/SKILL.md +30 -5
  228. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-human.mjs +3 -1
  229. package/plugins/src/base/skills/lisa-session-manager/scripts/cli-usage.mjs +11 -5
  230. package/plugins/src/base/skills/lisa-session-manager/scripts/human-needed.mjs +112 -5
  231. package/plugins/src/base/skills/lisa-session-manager/scripts/session-manager.mjs +5 -1
  232. package/plugins/src/base/skills/lisa-task-decomposition/SKILL.md +18 -0
@@ -27,6 +27,103 @@ export const HUMAN_NEEDED_KINDS = Object.freeze([
27
27
  "decision",
28
28
  ]);
29
29
 
30
+ /**
31
+ * Why a stop needed a human, as far as the planning-miss signal cares
32
+ * (CodySwannGT/lisa#4569). `planning` is the default: the item passed the
33
+ * ready gate and still needed a person. `environment` is an outage, an
34
+ * expired credential or a flaky tool; `human-gate` is a decision planning
35
+ * flagged as a human gate on the item. Neither of those two is a planning
36
+ * miss.
37
+ */
38
+ export const PLANNING_MISS_CAUSES = Object.freeze([
39
+ "planning",
40
+ "environment",
41
+ "human-gate",
42
+ ]);
43
+
44
+ /**
45
+ * Each kind that counts as a planning miss, with the planning stage most
46
+ * likely to have let it through. A hint for the judge, never its verdict:
47
+ * `learning-judge` names the stage it can prove.
48
+ */
49
+ const PLANNING_MISS_STAGES = Object.freeze({
50
+ // The stateless-pickup dry-run (S18) exists to find the question first.
51
+ "worker-question": "ready-gate",
52
+ // How the product should behave is the PRD's to decide.
53
+ decision: "prd",
54
+ // A leaf the router cannot place should have been split per repo-scope-split.
55
+ // Raised before the claim, but after the item passed the ready gate and was
56
+ // picked for dispatch: the operator ruled it a planning miss (#4569), and
57
+ // the planning-miss rate's denominator counts these routing holds too.
58
+ "repo-route": "decomposition",
59
+ });
60
+
61
+ /** Why a stop does not count, keyed by what ruled it out. */
62
+ const NOT_A_PLANNING_MISS = Object.freeze({
63
+ exhausted:
64
+ "repeated failed attempts are a build or environment problem, not a gap in the plan",
65
+ environment:
66
+ "an outage, an expired credential or a flaky tool is not a gap in the plan",
67
+ "human-gate":
68
+ "planning flagged this decision as a human gate, so asking was the plan working",
69
+ });
70
+
71
+ /**
72
+ * Whether a human-needed stop is a planning miss: the PRD, decomposition or
73
+ * ready gate let through an item a dispatched worker could not finish without
74
+ * a person. Throws on an unknown cause.
75
+ * @param {{kind: string, cause?: string}} input - The `--kind` and `--cause`
76
+ * @returns {{counts: boolean, reason: string, stageHint?: string}} Verdict
77
+ */
78
+ export function planningMissFor({ kind, cause = "planning" }) {
79
+ if (!PLANNING_MISS_CAUSES.includes(cause)) {
80
+ throw new Error(
81
+ `--cause must be one of: ${PLANNING_MISS_CAUSES.join(", ")}.`
82
+ );
83
+ }
84
+ if (cause !== "planning") {
85
+ return { counts: false, reason: NOT_A_PLANNING_MISS[cause] };
86
+ }
87
+ // Own keys only: an inherited name such as `toString` is not a kind.
88
+ const stageHint = Object.hasOwn(PLANNING_MISS_STAGES, kind)
89
+ ? PLANNING_MISS_STAGES[kind]
90
+ : undefined;
91
+ if (!stageHint) {
92
+ return { counts: false, reason: NOT_A_PLANNING_MISS.exhausted };
93
+ }
94
+ return {
95
+ counts: true,
96
+ stageHint,
97
+ reason:
98
+ "the item passed the ready gate and a dispatched worker still needed a human, so planning let a gap through",
99
+ };
100
+ }
101
+
102
+ /**
103
+ * The planning-miss verdict for `planMark`, plus the fields of the
104
+ * `lisa-persist-learning` candidate the manager can fill in without judgment.
105
+ * The rule and its why are the manager's to draft: they name the check
106
+ * planning should have run, which no script can know.
107
+ * @param {{ref: string, kind: string, cause?: string, question: string}}
108
+ * input - The item, why, the cause and the question text
109
+ * @returns {object} `{counts, reason, stageHint?, candidate?}`
110
+ */
111
+ function planningMissPlan({ ref, kind, cause, question }) {
112
+ const verdict = planningMissFor({ kind, cause });
113
+ if (!verdict.counts) return verdict;
114
+ return {
115
+ ...verdict,
116
+ candidate: {
117
+ signal: "planning-miss",
118
+ triggering_issue: ref,
119
+ provenance: [ref],
120
+ scope_hint: "project",
121
+ kind,
122
+ missing: question,
123
+ },
124
+ };
125
+ }
126
+
30
127
  /** Marks the manager's question comment, so its answer can be found after it. */
31
128
  export const QUESTION_MARKER = "[lisa-session-manager-question]";
32
129
 
@@ -134,13 +231,16 @@ function chooseMarker(label, blocked) {
134
231
  * unknown kind, empty or credential-shaped text, no marker, or an `exhausted`
135
232
  * item with no `blocked` role to move it to.
136
233
  * @param {{ref: string, kind: string, text: string, label?: string,
137
- * blocked?: string, channel?: boolean, answerers?: boolean}} input - The
138
- * item, why, the question, the configured human-needed label and `blocked`
139
- * role value, whether a notification channel exists, and whether anyone
140
- * (operatorIds / trustedAuthorIds) may answer on the item
234
+ * blocked?: string, channel?: boolean, answerers?: boolean, cause?: string}}
235
+ * input - The item, why, the question, the configured human-needed label
236
+ * and `blocked` role value, whether a notification channel exists, whether
237
+ * anyone (operatorIds / trustedAuthorIds) may answer on the item, and the
238
+ * cause the planning-miss signal needs (default `planning`)
141
239
  * @returns {{ref: string, kind: string, marker: {type: string, value: string},
142
240
  * move?: {role: "blocked", value: string}, comment: string,
143
- * answerWith: {item: string|null, cli: string, channel: string|null}}} Plan
241
+ * answerWith: {item: string|null, cli: string, channel: string|null},
242
+ * planningMiss: {counts: boolean, reason: string, stageHint?: string,
243
+ * candidate?: object}}} Plan
144
244
  */
145
245
  export function planMark({
146
246
  ref,
@@ -150,10 +250,16 @@ export function planMark({
150
250
  blocked,
151
251
  channel = false,
152
252
  answerers = true,
253
+ cause = "planning",
153
254
  }) {
154
255
  if (!HUMAN_NEEDED_KINDS.includes(kind)) {
155
256
  throw new Error(`--kind must be one of: ${HUMAN_NEEDED_KINDS.join(", ")}.`);
156
257
  }
258
+ if (!PLANNING_MISS_CAUSES.includes(cause)) {
259
+ throw new Error(
260
+ `--cause must be one of: ${PLANNING_MISS_CAUSES.join(", ")}.`
261
+ );
262
+ }
157
263
  const question = String(text ?? "").trim();
158
264
  if (question === "") throw new Error("the question or reason is empty");
159
265
  const shape = findCredentialShape(question);
@@ -194,5 +300,6 @@ export function planMark({
194
300
  cli: `the answerCommand that session-manager.mjs status lists for ${ref} (answer on stdin)`,
195
301
  channel: channel ? `Answer with: ${short} <your answer>` : null,
196
302
  },
303
+ planningMiss: planningMissPlan({ ref, kind, cause, question }),
197
304
  };
198
305
  }
@@ -111,7 +111,11 @@ const COMMANDS = {
111
111
  options: { input: text, ref: text },
112
112
  positionals: 0,
113
113
  },
114
- "mark-plan": { run: markPlan, options: { kind: text }, positionals: 1 },
114
+ "mark-plan": {
115
+ run: markPlan,
116
+ options: { kind: text, cause: text },
117
+ positionals: 1,
118
+ },
115
119
  answer: { run: answer, options: {}, positionals: 1 },
116
120
  "item-answer": { run: itemAnswer, options: {}, positionals: 1 },
117
121
  "record-cycle": {
@@ -9,6 +9,24 @@ Break work into ordered, well-scoped tasks that can be independently implemented
9
9
 
10
10
  ## Decomposition Process
11
11
 
12
+ ### 0. Load the learned planning checks
13
+
14
+ Every time a dispatched worker had to stop for a human, or file a new ticket mid-build, because planning let a gap through, `learning-judge` may have persisted the check planning should have run as a `planning-miss` learning (CodySwannGT/lisa#4569). Those checks only help if planning reads them back. Before decomposing, load them through the learnings contract's **bounded projection** — never by reading the ledger file wholesale:
15
+
16
+ ```bash
17
+ node -e 'import("@codyswann/lisa/learnings").then(async m => { const { readFile } = await import("node:fs/promises"); const file = m.resolveProjectLearningsFile(await m.readProjectConfig(process.cwd())); const raw = await readFile(file, "utf8").catch(() => null); if (raw === null) return; const { entries, omittedCount } = m.projectLearnings(m.parseLearningsFile(raw)); const checks = entries.filter(e => /^Planning \((prd|decomposition|ready-gate)\):/.test(e.rule)).map(e => ({ id: e.id, rule: e.rule, confidence: e.confidence })); console.log(JSON.stringify({ checks, omittedCount })); }).catch(error => console.error(`learned planning checks unavailable: ${error.message}`))' || true
18
+ ```
19
+
20
+ Run it from the project root. No output means there is no ledger yet: carry on. A malformed ledger prints one warning and yields nothing: carry on without it. Never let this step block planning.
21
+
22
+ Each check names the stage that owns it, and binds there:
23
+
24
+ - **`Planning (prd): …`** — a requirement the PRD must settle. In PRD intake (`*-to-tracker` Phase 1.45) a register entry that fails one is a `product-clarity` item, like any other requirement-quality failure.
25
+ - **`Planning (decomposition): …`** — binds in this skill: apply each as an extra obligation on every work unit it concerns, alongside steps 1–6 below. A unit that cannot meet it is split, re-scoped or given its missing dependency now, not left for the worker to discover.
26
+ - **`Planning (ready-gate): …`** — binds in the validator's S18 stateless-pickup dry-run (`lisa-jira-validate-ticket`, `lisa-github-validate-issue`, `lisa-linear-validate-issue`): each becomes a question the dry-run must be able to answer from the item and the links it can resolve.
27
+
28
+ A check is a learned heuristic, not a new gate number: cite its `id` where it changed a decision, so `last_confirmed` can be advanced at claim time (`project-learnings`). When a check plainly does not apply to this work, skip it silently.
29
+
12
30
  ### 1. Identify Units of Work
13
31
 
14
32
  - Break the work into the smallest units that are independently valuable
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "4.86.1",
3
+ "version": "4.87.1",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: learning-judge
3
- description: Skeptical judgment gate for candidate learnings. Classifies each candidate as durable-learning, one-off, misunderstanding/spec-gap, or lisa-upstream with mandatory evidence citation. Hostile default — most candidates are DROPPED; only durable-learning ever persists. Use whenever a failure signal or debrief produces a claimed learning that something wants to write to the project learnings surface.
3
+ description: Skeptical judgment gate for candidate learnings. Classifies each candidate as durable-learning, planning-miss, one-off, misunderstanding/spec-gap, or lisa-upstream with mandatory evidence citation. Hostile default — most candidates are DROPPED; only durable-learning and planning-miss (a dispatched item that needed a human because planning let a gap through) persist. Use whenever a failure signal or debrief produces a claimed learning that something wants to write to the project learnings surface.
4
4
  ---
5
5
 
6
6
  # Learning Judge Agent
@@ -30,6 +30,7 @@ Each candidate you evaluate is a single object:
30
30
  | `evidence_links[]` | string[] | Concrete evidence URLs/refs available for citation (failure logs, rejection comments, prior incidents). |
31
31
  | `scope_hint` | `project` \| `upstream` | The submitter's guess at where the learning belongs. A hint only — attribution below decides. |
32
32
  | `triggering_issue` | string | The issue/work item whose failure produced this candidate. |
33
+ | `signal` | `planning-miss` \| absent | Set by a caller that saw a dispatched item stop for a human or file a new ticket mid-build (`lisa-session-manager`, `lisa-implement`). A hint only — Step 2.5 decides. |
33
34
  | `fingerprint` | string | Stable dedupe key for this candidate (computed by the caller, e.g. `lisa-persist-learning`). Echo it back unchanged. |
34
35
 
35
36
  A candidate missing `triggering_issue` or with an empty evidence set can still be evaluated — but it can never reach `durable-learning`, because the mandatory citations below would be impossible.
@@ -51,27 +52,41 @@ Determine what actually caused the failure. If the root cause is a Lisa-shipped
51
52
  Only candidates that survive Steps 0–1 continue. Answer both questions, each with **cited** concrete evidence (from `evidence_links`, `provenance`, or your own tracker/repo lookup):
52
53
 
53
54
  1. **Prevention** — Would this exact rule, had it existed, have prevented the triggering failure? Re-walk the failure with the rule in force. If the failure would have happened anyway, the rule is a superstition: not durable.
54
- 2. **Recurrence** — Does the failure **class** recur? Cite concrete references: a prior issue, PR, revert, rejection comment, or incident showing the same class of mistake on a different occasion. **No recurrence evidence ⇒ never `durable-learning`.** A single occurrence, however painful, is `one-off` — the class may prove itself later, and the candidate can return with evidence.
55
+ 2. **Recurrence** — Does the failure **class** recur? Cite concrete references: a prior issue, PR, revert, rejection comment, or incident showing the same class of mistake on a different occasion. **No recurrence evidence ⇒ never `durable-learning`.** A single occurrence, however painful, is `one-off` — the class may prove itself later, and the candidate can return with evidence. The one exception is a requirement gap that reached a dispatched worker: judge it under Step 2.5 before concluding `one-off`.
55
56
 
56
57
  Do not accept the candidate's own `why` as evidence — it is the claim under test.
57
58
 
58
- ### Step 3: Classify (4-way taxonomy)
59
+ ### Step 2.5: Planning miss (a gap planning let through)
60
+
61
+ A missing, ambiguous, contradictory or undecided requirement is not always a one-ticket problem. PRD intake, decomposition and the ready gate (`work-item-definition-of-ready`, the S18 stateless-pickup dry-run) exist so a dispatched worker never needs a human. When one does, the item's own question gets answered on the item, but the process that let it through is unchanged — dropping the signal guarantees the next PRD repeats it. So a requirement gap is a `planning-miss`, not a drop, when **all** of these hold, each established by cited evidence rather than the candidate's word. (The planning skills are Lisa-shipped, but that alone does not make the miss `lisa-upstream` in Step 1: a check about this project's domain — its report formats, its repos, its integrations — belongs here. Only a domain-free check every project's planning would miss is a Lisa gate defect.)
62
+
63
+ 1. **It was dispatched.** The item had passed the ready gate — it was in the ready role and was picked up for dispatch — claimed by a worker, or held by the dispatcher while routing it to a repository (a `repo-route` hold: the item is past the ready gate and mid-dispatch, and `repo-scope-split` at decomposition should have made the route unambiguous) — before the gap surfaced. Cite the claim, the dispatch, or the ready-role history. A gap found at PRD intake, during validation, or before the ready flip is the gate **working**: that is `misunderstanding/spec-gap`.
64
+ 2. **The information really was missing.** Quote what the worker could not find, and confirm it is absent from the item and the links it resolves. If the answer was on the item and the worker misread it, it is `misunderstanding/spec-gap` (the worker's defect, not planning's).
65
+ 3. **It is not environmental or planned.** An outage, an expired credential, a flaky tool, missing tool access (`tool-access-gate`), or a decision planning **flagged as a human gate** on the item (`human_gate`, `[lisa-human-gate]`) is not a planning miss: asking there was the plan working. Neither is an item that exhausted its attempts.
66
+ 4. **A planning check would have caught it.** This is Step 2's prevention question, asked of planning instead of the build. Name the stage that should have caught it — `prd` (the requirement was never decided), `decomposition` (the work was mis-scoped, mis-split, or depended on something nobody filed, including a leaf the router could not place in one repo per `repo-scope-split`), or `ready-gate` (the item looked ready but S18 should have asked the question) — and re-walk it: with the check in force, the item would not have reached Ready with this gap.
67
+
68
+ **The rule is the check planning should have run, never the answer.** Rewrite the candidate's `rule` as `Planning (<stage>): <check>` — e.g. `Planning (decomposition): an export ticket must name its report format before it is Ready.` — never `Exports use CSV.`, which only answers the one ticket and belongs on the item. A rule that only makes sense for this one item is not a check: drop it as `misunderstanding/spec-gap`. The `why` names the stage that let it through and quotes what the worker could not find. The prefix is load-bearing: planning skills select these entries from the bounded projection by it (`lisa-task-decomposition` step 0).
69
+
70
+ **Recurrence never blocks a first occurrence.** A first-occurrence planning miss persists at `low` confidence, so its persistence PR waits for a human to merge it. That is a deliberate, bounded exception to Step 2's recurrence requirement. The hostile default exists because a plausible-but-wrong rule would reach every future session unattended; a `low` rule never does, because a human reads it at the gate first. Meanwhile the signal is unusually strong and unusually rare: each occurrence already cost the human interruption the gate exists to prevent, so waiting for a second occurrence costs a second interruption and teaches nothing new. And the rule only adds a check to planning — a wrong one costs a planning question, not changed build behaviour. With recurrence evidence (another dispatched item that stopped on the same class of gap), Step 4 may grant `high`.
71
+
72
+ ### Step 3: Classify (5-way taxonomy)
59
73
 
60
74
  Exactly one of:
61
75
 
62
- - **`durable-learning`** — both falsification questions pass with cited evidence. The only classification that persists. Disposition `persist`.
76
+ - **`durable-learning`** — both falsification questions pass with cited evidence. Disposition `persist`.
77
+ - **`planning-miss`** — every Step 2.5 condition holds: the item was dispatched past the ready gate, the information really was missing, the cause is not an outage, an expired credential, a flaky tool or a decision flagged as a human gate, and a named planning check would have caught it. Disposition `persist`, with `planning_stage` set and `rule` rewritten as the check.
63
78
  - **`one-off`** — a genuine typo, transient fluke, or single-occurrence mistake with no recurrence evidence. Disposition `drop`.
64
- - **`misunderstanding/spec-gap`** — the failure traces to an ambiguous or missing requirement, not an agent defect. The fix is a better spec (raise it on the work item), not a rule. Disposition `drop`.
79
+ - **`misunderstanding/spec-gap`** — the failure traces to an ambiguous or missing requirement caught **before** the item was dispatched (the gate worked), or to information the item did hold that was misread. The fix is a better spec (raise it on the work item), not a rule. Disposition `drop`.
65
80
  - **`lisa-upstream`** — set in Step 1. Disposition `handoff-upstream`; never persisted locally.
66
81
 
67
- When multiple classifications seem defensible, choose the one that does **not** persist — the hostile default.
82
+ When multiple classifications seem defensible, choose the one that does **not** persist — the hostile default. Dispatch is a fact, not a judgement call: if you cannot cite that the item passed the ready gate and was dispatched, it is not `planning-miss`.
68
83
 
69
- ### Step 4: Confidence (durable-learning only)
84
+ ### Step 4: Confidence (durable-learning and planning-miss)
70
85
 
71
86
  - **`high`** — the causal story is unambiguous and the recurrence citations are directly on point. The persistence PR may merge through the project's normal gates unattended.
72
87
  - **`low`** — durable on the evidence, but the causal chain has an inferential step or the recurrence evidence is indirect. The persistence PR must wait for a human (auto-merge off + triage label).
73
88
 
74
- If you cannot justify `high` in one sentence a non-engineer would accept, it is `low`.
89
+ If you cannot justify `high` in one sentence a non-engineer would accept, it is `low`. A `planning-miss` with no recurrence citation is always `low`.
75
90
 
76
91
  ## Verdict Output Schema
77
92
 
@@ -79,11 +94,13 @@ Return exactly one verdict object per candidate:
79
94
 
80
95
  | Field | Type | Meaning |
81
96
  |-------|------|---------|
82
- | `classification` | `durable-learning` \| `one-off` \| `misunderstanding/spec-gap` \| `lisa-upstream` | The Step 3 outcome. |
97
+ | `classification` | `durable-learning` \| `planning-miss` \| `one-off` \| `misunderstanding/spec-gap` \| `lisa-upstream` | The Step 3 outcome. |
83
98
  | `cited_evidence[]` | string[] | The concrete refs you actually relied on for this call — prevention and recurrence citations for durable; attribution citations for upstream; the decisive absence/counter-evidence for drops. Never empty. This is what makes a wrong call auditable. |
84
99
  | `rationale` | string | 1–3 sentences readable by product, engineering, and QA alike (a non-technical operator stands at the gate). |
85
- | `confidence` | `high` \| `low` | Present **only** when `classification` is `durable-learning`. |
86
- | `disposition` | `persist` \| `drop` \| `handoff-upstream` | `persist` iff durable-learning; `handoff-upstream` iff lisa-upstream; otherwise `drop`. |
100
+ | `confidence` | `high` \| `low` | Present **only** when `classification` is `durable-learning` or `planning-miss`. |
101
+ | `planning_stage` | `prd` \| `decomposition` \| `ready-gate` | Present **only** when `classification` is `planning-miss`: the stage that let the gap through. |
102
+ | `rule` | string | Present **only** when `classification` is `planning-miss`: the candidate's rule rewritten as the `Planning (<stage>): <check>` check, within the contract's caps. The caller persists this text, not the submitted one. |
103
+ | `disposition` | `persist` \| `drop` \| `handoff-upstream` | `persist` iff durable-learning or planning-miss; `handoff-upstream` iff lisa-upstream; otherwise `drop`. |
87
104
 
88
105
  Also echo back the candidate's `fingerprint` and `triggering_issue` so the caller can route without re-deriving them.
89
106
 
@@ -102,9 +119,12 @@ Also echo back the candidate's `fingerprint` and `triggering_issue` so the calle
102
119
  | Attribution (Lisa vs project) | project/lisa-upstream | [refs] |
103
120
  | Prevention (would the rule have prevented it?) | yes/no | [refs] |
104
121
  | Recurrence (does the class recur?) | yes/no | [refs] |
122
+ | Planning miss (dispatched, really missing, not environmental or a flagged gate, planning check named) | yes/no/n-a | [refs] |
105
123
 
106
- **Classification**: durable-learning | one-off | misunderstanding/spec-gap | lisa-upstream
107
- **Confidence**: high | low (durable-learning only)
124
+ **Classification**: durable-learning | planning-miss | one-off | misunderstanding/spec-gap | lisa-upstream
125
+ **Planning stage**: prd | decomposition | ready-gate (planning-miss only)
126
+ **Rule**: Planning (<stage>): <check> (planning-miss only — the rewritten rule the caller persists)
127
+ **Confidence**: high | low (durable-learning and planning-miss only)
108
128
  **Disposition**: persist | drop | handoff-upstream
109
129
  **Rationale**: [1–3 plain-language sentences]
110
130
  ```
@@ -112,7 +132,7 @@ Also echo back the candidate's `fingerprint` and `triggering_issue` so the calle
112
132
  ## Important Reminders
113
133
 
114
134
  1. **Most candidates DROP** — a session where you persist everything you saw is a failed gate, not a productive one.
115
- 2. **No recurrence citation, no durable-learning** — this is absolute; there are no exceptions for "obviously true" rules.
135
+ 2. **No recurrence citation, no durable-learning** — this is absolute; there are no exceptions for "obviously true" rules. A `planning-miss` is not a durable-learning: without recurrence it persists only at `low`, behind a human merge, and the recurrence requirement never blocks a first occurrence of it.
116
136
  3. **Cite what you relied on** — a verdict without `cited_evidence` is invalid; re-run the evaluation.
117
137
  4. **`lisa-upstream` never becomes a local rule** — classify and hand off; filing the upstream ticket is the caller's flow, not yours.
118
138
  5. **You classify; you do not write** — never touch the learnings surface, post comments, or open PRs. The caller (`lisa-persist-learning`) owns all side effects.
@@ -105,6 +105,10 @@ Any defect discovered while doing something else, which is complete enough to bu
105
105
 
106
106
  The same explicitness applies in the other direction. A filing that is genuinely a human product call declares `human_gate`; it does not simply omit the flag and hope the tracker default is the merciful one.
107
107
 
108
+ ## Mid-build filings are a planning signal
109
+
110
+ A ticket a worker has to file **while building** a dispatched item, because that item was mis-scoped, mis-split, or depends on work nobody filed, is filed exactly as above. It is also evidence that planning let a gap through, and it is routed as such: the filer sends one `planning-miss` candidate through `lisa-persist-learning`, with the item being built (never the new ticket) as `triggering_issue` and the check planning should have run as the rule. `lisa-implement` owns the step and its exclusions (outages, credentials, tool access, flaky tools, and decisions planning flagged as human gates); the judge decides whether it really was a miss. The signal never delays or changes the filing.
111
+
108
112
  ## The named exception: `lisa-exploratory-qa`
109
113
 
110
114
  `lisa-exploratory-qa` files its findings **not** build-ready by default, and that is **correct** — it is the named human-gate exception under this rule, not drift to be repaired.
@@ -167,6 +167,14 @@ the caller posts to the source. This is the enforcement of the intake
167
167
  contract's core promise, and of TASC AC8.6: *ready means zero-clarification
168
168
  executable.*
169
169
 
170
+ The dry-run also asks the **learned planning checks**: `planning-miss`
171
+ learnings, the check planning should have run, persisted by `learning-judge`
172
+ each time a dispatched worker still had to stop for a human or file a ticket
173
+ mid-build (CodySwannGT/lisa#4569). They are read through the learnings
174
+ contract's bounded projection (`lisa-task-decomposition` step 0), never the raw
175
+ ledger. A worker that stops anyway is the signal this gate missed something,
176
+ and the loop turns that stop into the next item's question.
177
+
170
178
  ## Relationship to the lifecycle
171
179
 
172
180
  - **Write time** — `*-write-*` runs the applicable pre-write gates; a spec
@@ -240,6 +240,11 @@ planning proceeds. Per atom:
240
240
  requirement.
241
241
  - **Pattern shape (SHOULD)** — an EARS pattern (ubiquitous / When / While / If-then / Where) or an
242
242
  equivalent single-behavior sentence; conforming shapes decompose into Gherkin mechanically.
243
+ - **Learned planning checks** — load the `Planning (...)` checks through the bounded projection
244
+ (`lisa-task-decomposition` step 0). Test the register against every `Planning (prd)` check; an
245
+ atom or a missing atom that fails one is a `product-clarity` item quoting the check, exactly
246
+ like the failures above. Carry the `Planning (decomposition)` checks into Phases 3–5. Each is
247
+ a gap a dispatched worker once had to stop and ask about, so catching it here is the point.
243
248
 
244
249
  Failures here are **requirement-level product clarifications**, not internal errors: report each in
245
250
  the dry-run report as a `product-clarity` item quoting the atom verbatim, naming the defect, and
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: lisa-delivery-effectiveness
3
- description: "Measure whether the work the factory delivers was worth shipping — gate rejection, rework, escape, first-pass yield and cost per delivered item — so autonomy rate cannot stand alone as a success measure."
3
+ description: "Measure whether the work the factory delivers was worth shipping — gate rejection, rework, escape, first-pass yield, cost per delivered item and planning-miss rate — so autonomy rate cannot stand alone as a success measure."
4
4
  allowed-tools: ["Read", "Grep", "Glob", "Bash"]
5
5
  ---
6
6
 
@@ -8,7 +8,7 @@ allowed-tools: ["Read", "Grep", "Glob", "Bash"]
8
8
 
9
9
  Autonomy rate answers how much ran without a human. It says nothing about whether any of it should have shipped, and on its own it rewards exactly the wrong thing: a factory that produces rejected work faster scores better.
10
10
 
11
- ## The five measures
11
+ ## The six measures
12
12
 
13
13
  Each needs a stated numerator, denominator and window, or it is a number-shaped opinion.
14
14
 
@@ -19,8 +19,11 @@ Each needs a stated numerator, denominator and window, or it is a number-shaped
19
19
  | **Escape rate** | Defects reaching production, over items released | What the gates did not catch |
20
20
  | **First-pass yield** | Items reaching terminal state with no rework, over items started | The one number that moves only when the whole line works |
21
21
  | **Cost per delivered item** | Metered spend, over items reaching terminal state | What a unit of accepted output actually costs |
22
+ | **Planning-miss rate** | Items carrying a `[lisa-planning-miss]` note, over items picked up for dispatch (entered the claimed role, or were held by the dispatcher at repository routing) | How often planning let through work a worker could not finish without a human |
22
23
 
23
- First-pass yield is the summary measure worth watching, because every other failure shows up in it. The other four exist to tell you *where* it went.
24
+ First-pass yield is the summary measure worth watching, because every other failure shows up in it. The other five exist to tell you *where* it went.
25
+
26
+ The planning-miss rate is the one that points upstream of the build. Its numerator is the `[lisa-planning-miss]` note `lisa-persist-learning` leaves on an item when `learning-judge` confirms that a dispatched worker had to stop for a human, or file a new ticket mid-build, because planning let a gap through. Count distinct items, not notes. The note is posted only on a confirmed miss, so outages, expired credentials, flaky tools and decisions planning flagged as human gates are already out of it. Both halves come from the tracker. Each persisted miss also becomes a planning check that PRD intake, decomposition and the ready gate read back, so better planning shows up as this number falling.
24
27
 
25
28
  ## Where the numbers come from
26
29
 
@@ -55,6 +58,7 @@ Report both, together, always. The pairing is the point:
55
58
  | Escape rate | | | | | |
56
59
  | First-pass yield | | | | | |
57
60
  | Cost per delivered item | | | | | |
61
+ | Planning-miss rate | | | | | |
58
62
 
59
63
  **Reading:** which of the four autonomy/yield quadrants this window sits in
60
64
  **Uncollected:** any measure not gathered, and why — never an estimate in its place
@@ -391,15 +391,16 @@ declared, arm normally (the scope rule above). Where one IS declared, absent a
391
391
  description that positively states a review ran, treat the context as vacuous.
392
392
  Fail closed: absence of evidence is not evidence of a review.
393
393
 
394
- #### Vacuous and transient are different properties
394
+ #### Vacuous, transient or standing: the response is the same
395
395
 
396
- A vacuous context is not automatically something to wait out, and this is the
397
- distinction a naive wait-and-arm gets wrong — it waits forever on a repository
398
- where the state never clears. **Only the rate limit has both properties.**
396
+ A vacuous context is never something to wait out. Waiting looks like progress
397
+ but it is a stall, and on a repository where the state never clears it waits
398
+ forever. Some vacuities clear on their own and some do not. **That changes what
399
+ the report says, not what you do:**
399
400
 
400
401
  | description | vacuous? | clears on its own? |
401
402
  | --- | --- | --- |
402
- | `Review rate limited` | yes | **yes** — a throughput window |
403
+ | `Review rate limited` (and decorated forms such as `Review rate limited (retry in 12m)`) | yes | eventually — a throughput window of unknown length |
403
404
  | `Review skipped: manual review required for this OSS repository` | yes | **no** — a standing vendor policy for public repositories |
404
405
  | `Review skipped: N files exceed the limit of M` | yes | **no** — not without splitting the pull request |
405
406
  | `Review skipped` (bare, no stated reason) | yes | **unknown — treat as standing** |
@@ -408,17 +409,33 @@ A bare skip carries no machine-readable reason, so nothing distinguishes it from
408
409
  the standing forms. Requiring a stated reason before treating a skip as vacuous
409
410
  is how the commonest form gets missed.
410
411
 
411
- - **Transient (the rate limit, and only the rate limit)** — do not arm yet. Wait
412
- the window out and re-request the review **at most once**, then re-classify.
413
- If it now proves work, arm. If it does not, stop and treat it as standing.
414
- **Never loop**: a retry loop re-triggers the very limit it is escaping, and
415
- measured on #3220 a single explicit re-request in this repository was
416
- acknowledged, went `Review in progress`, and settled back at
417
- `Review rate limited` two seconds later having reviewed nothing — minting a
418
- second hollow green. One attempt, then report.
419
- - **Standing** — do not wait at all, and do not re-request. There is no window
420
- to wait out, so waiting produces a stall that reads as progress. Go straight
421
- to the watch loop and let step (d) adjudicate the merge in the open.
412
+ **Every row, the rate limit included: do not wait, and do not re-request.** Do
413
+ not arm. Go straight to the watch loop, run the local adversarial review over the
414
+ PR diff at the current head **now**, post it with the substitute marker (step
415
+ (d), "In case 3, substitute"), and keep driving. Fix what it finds, substitute
416
+ again on each new head, and let step (d) merge when the vacuous context is the
417
+ sole remaining gate.
418
+
419
+ The rate limit used to get a wait-the-window-out-and-re-request-once exception.
420
+ That exception is removed, for three reasons:
421
+
422
+ - **The window is not short.** Agents waiting it out stalled for an hour or more
423
+ per pull request, across a whole portfolio of repositories, and nothing about
424
+ the wait made the merge safer than a substitute review would.
425
+ - **Re-requesting does not work under a throttle.** Measured on #3220, a single
426
+ explicit re-request was acknowledged, went `Review in progress`, and settled
427
+ back at `Review rate limited` two seconds later having reviewed nothing. That
428
+ minted a second hollow green.
429
+ - **Re-requesting destroys evidence.** It overwrites the existing status (see
430
+ "Never re-request a review to 'refresh' it" in step (d)), so the exception
431
+ contradicted a rule this file states with no exceptions.
432
+
433
+ If the reviewer later reviews on its own, nothing special happens. Its threads
434
+ are review threads like any other, and step (d) handles them. A `CHANGES_REQUESTED`
435
+ it leaves is a real blocker (step (e)), and the substitute never overrides it.
436
+ If it now proves work, arm, per the table above. That is a re-classification
437
+ the watch loop makes on what it reads anyway. It is never a reason to wait or
438
+ re-request.
422
439
 
423
440
  #### A latch somebody else armed
424
441
 
@@ -1046,10 +1063,11 @@ configured reviewed-when phrase says what "did work" looks like for this
1046
1063
  project.
1047
1064
 
1048
1065
  Prove the signal from the commit status API as above; a merely pending or queued
1049
- check is not proof of anything and must keep polling. **A transient vacuity is not adjudicated here until the arm gate's
1050
- single wait-and-re-request has been spent** (section 1): a rate limit has a
1051
- window, and merging past one you never waited out is a choice you did not have
1052
- to make. A standing vacuity has no window, so it arrives here immediately.
1066
+ check is not proof of anything and must keep polling. **A settled vacuity, the
1067
+ rate limit included, arrives here immediately.** There is no wait to spend first
1068
+ and no re-request to try: a rate limit's window is of unknown length, and
1069
+ waiting it out stalls the pull request without reading a line of the diff. The
1070
+ substitute is what makes the merge safe, not the passage of time.
1053
1071
 
1054
1072
  Once the signal is explicit, merge directly with `gh pr merge <pr>
1055
1073
  --<merge_method>` (pass `--admin` only if branch protection lists the vacuous
@@ -1170,6 +1188,34 @@ Deleting the fallback outright would over-correct: it is the only remedy a lane
1170
1188
  without dismissal permission has, and that permission is not universal. This
1171
1189
  narrows it to the case that costs nothing.
1172
1190
 
1191
+ **A stale bot verdict under a rate limit: substitute, then stop and report.**
1192
+ Under a rate limit or an exhausted review allowance, a bot's old
1193
+ `CHANGES_REQUESTED` on an outdated head can end up as the only thing blocking
1194
+ the merge. The bot cannot post a fresh review to replace it, so the verdict
1195
+ will not clear by itself while the throttle lasts. This was measured on a
1196
+ caller repo in the portfolio: every check green, zero unresolved threads, and
1197
+ the bot's verdict from an earlier head as the only blocker. In that case:
1198
+
1199
+ 1. **Do not wait for the window to reset, and do not re-request.** Waiting
1200
+ leaves the pull request wedged for an hour or more. A re-request under the
1201
+ throttle settles hollow and can take away the bot's standing review (see
1202
+ above).
1203
+ 2. Post the local adversarial review substitute for the **current** head, as
1204
+ step (d) case 3 describes, if one is not already there.
1205
+ 3. **Then stop** with `blocked:stale-bot-verdict` (section 4). Report exactly
1206
+ that blocker: the bot reviewer, the review id, the outdated head it reviewed
1207
+ and the current head, the unresolved thread count, and that the substitute
1208
+ is posted for the current head. Name the decision that is needed: a human
1209
+ with dismissal rights dismisses that review, or decides it must stand.
1210
+
1211
+ Do not dismiss it on the strength of your own substitute. Here the bot's review
1212
+ is the only third-party review on the pull request. Dismissing it because of a
1213
+ review this run wrote would make the agent both author and judge of the change.
1214
+ That is the escalation the bullet above requires, reached right away instead of
1215
+ after a wait. A stranded verdict that is **not** the only substantive review, or
1216
+ one left by a reviewer that is not throttled, is still handled by the
1217
+ dismissal rule above.
1218
+
1173
1219
  **Unverified, and stated as such rather than asserted:** that a bot's re-review
1174
1220
  REPLACES its predecessor in the effective set is inferred from the observed
1175
1221
  consequence, not measured against the vendor. It has not been tested here, and
@@ -1453,7 +1499,7 @@ Loop until one of:
1453
1499
  the mode forbids acting on them: `on_blocker=report`). The latch is
1454
1500
  deliberately not armed, so the PR sits OPEN rather than merging on a review
1455
1501
  nothing performed. Report the PR URL, the review context's settled
1456
- description, whether it is transient or standing, and which sole-gate
1502
+ description, whether it clears on its own (a rate limit) or is standing, and which sole-gate
1457
1503
  condition failed. This is an outcome that needs an operator, stated in one
1458
1504
  line a non-technical reader can act on — for example: *"PR #123 is ready to
1459
1505
  merge but nobody reviewed it: the review tool says it skips public
@@ -1483,6 +1529,16 @@ Loop until one of:
1483
1529
  — but a review asked for changes and that is still on record, so it will sit
1484
1530
  there forever. Someone needs to clear that review or resolve the open
1485
1531
  comments."* Never report this PR as merging.
1532
+ - **`blocked:stale-bot-verdict`** — the only thing blocking the merge is a
1533
+ bot's `CHANGES_REQUESTED` on an outdated head, the bot is rate limited or out
1534
+ of review allowance so it cannot replace that verdict, and the local
1535
+ adversarial review substitute is posted for the current head (step (e)).
1536
+ Report the reviewer, the review id, both heads, the unresolved thread count,
1537
+ and the dismissal decision a human needs to make. For example: *"PR #123 is
1538
+ ready except for an old review from the review bot on an earlier version. The
1539
+ bot is rate limited and cannot re-review, and I posted my own review of the
1540
+ current version. Someone with dismissal rights needs to dismiss review 456,
1541
+ or decide it should stand."* Do not wait for the bot's window to reset.
1486
1542
  - **`CLOSED`** → report (PR was closed without merge).
1487
1543
  - **Hard block needing a human**: an unresolvable conflict, a failing check that
1488
1544
  needs design input, or genuine unresolved human objection (not a bot gate). Stop
@@ -1591,7 +1647,8 @@ declare none, one, or several, and each shows its own evidence.
1591
1647
 
1592
1648
  Quote the description that was actually read. A report that says "rate limited"
1593
1649
  on a policy skip is a wrong record, and the two call for different operator
1594
- actions: one clears itself, the other never will.
1650
+ actions: one clears itself, the other never will. Neither changes what this
1651
+ skill does in the meantime: it substitutes and keeps driving in both cases.
1595
1652
 
1596
1653
  `NOT REVIEWED` is reporting, and on a merged PR it is never a terminal state of
1597
1654
  its own: it does not turn a merged PR into a blocked one. What it does gate is
@@ -227,6 +227,11 @@ planning proceeds. Per atom:
227
227
  requirement.
228
228
  - **Pattern shape (SHOULD)** — an EARS pattern (ubiquitous / When / While / If-then / Where) or an
229
229
  equivalent single-behavior sentence; conforming shapes decompose into Gherkin mechanically.
230
+ - **Learned planning checks** — load the `Planning (...)` checks through the bounded projection
231
+ (`lisa-task-decomposition` step 0). Test the register against every `Planning (prd)` check; an
232
+ atom or a missing atom that fails one is a `product-clarity` item quoting the check, exactly
233
+ like the failures above. Carry the `Planning (decomposition)` checks into Phases 3–5. Each is
234
+ a gap a dispatched worker once had to stop and ask about, so catching it here is the point.
230
235
 
231
236
  Failures here are **requirement-level product clarifications**, not internal errors: report each in
232
237
  the dry-run report as a `product-clarity` item quoting the atom verbatim, naming the defect, and
@@ -345,6 +345,8 @@ Without a baseline and a target an Improvement has no verifiable terminal state
345
345
 
346
346
  The autonomy gate, run last, on every build-ready leaf (use the S15 classification; `N/A` for containers and non-build-ready items). Simulate a stateless agent reading only this item and the links it can resolve — session knowledge about the codebase does not count, because the next claimant will not have it. List every question that agent would have to ask a human before starting work, before choosing between materially different implementations, or before declaring the work done.
347
347
 
348
+ **Learned planning checks.** Questions that past dispatched workers actually had to stop and ask are the best predictor of the next one. Load the `Planning (...)` checks through the bounded projection exactly as `lisa-task-decomposition` step 0 does, and add each one that applies to this item as a question the simulated agent must be able to answer from the item and the links it can resolve, the same reach S18 already allows. One it cannot answer is a FAIL question like any other, quoting the check's rule. No ledger, or a malformed one, adds nothing and never fails this gate.
349
+
348
350
  Zero questions → PASS. Any question → FAIL, with each question listed verbatim as its own remediation line — these are exactly the clarifying comments the caller posts to the source. The structure gates are proxies; this gate checks the readiness property itself: `ready` means a stateless agent can drive this item to its terminal state with zero human clarification (see `work-item-definition-of-ready`).
349
351
 
350
352
  #### S19 — Branch Plan derivation
@@ -345,6 +345,8 @@ Before shutting down the team, execute the Verify flow:
345
345
  - **Actionable blocker** — an unresolved dependency or fixable technical gap that some team or repository could build (a missing or changed schema field, an unbuilt sibling work item, a required upstream fix), **including cross-repo dependencies**. Before writing the blocked verdict you MUST (1) file a build-ready fix/dependency ticket capturing the diagnosis — in the dependency's own repository/tracker when it is cross-repo (e.g. a `[<repo>] …` ticket in the shared project, or the sibling tracker) — and (2) link the current work item to it as `is blocked by`. Only then write the verdict. This is the same discipline as the regression-spec blocker and the remote-verification-fail exits above, and it is what makes the block machine-recoverable: `repair-intake` re-dispatches a blocked item once its linked `is blocked by` dependency closes, but it cannot act on a prose-only comment. Recommending the ticket "as a human follow-up" without filing and linking it is **not** a permitted exit.
346
346
  - **Human-only blocker** — an input the agent genuinely cannot obtain or produce no matter what it does: credentials, secrets, or **tool access** it does not have (AWS/CloudWatch, Figma, Jam, Sentry, SonarCloud, a database, a protected deploy target, …), or a product/design decision only a human can make. For missing tool access, follow the `tool-access-gate` rule's break-out protocol: post the "Access Needed" comment naming the exact credential/role/env var to grant and the probe that must pass — never work around the gap by substituting weaker verification, mocking the inaccessible system, or narrowing scope. Record the blocked verdict, mark it `human_needed` (the marker `repair-intake` recognizes, so it won't churn re-dispatching it), and surface or reassign to a human; do **not** fabricate a build-ready ticket, because there is no build-ready work.
347
347
 
348
+ **Planning-miss signal.** Either exit can mean planning let a gap through, and that signal is worth more than the one ticket (CodySwannGT/lisa#4569). It is a planning miss when you file a new ticket mid-build because this item was mis-scoped, mis-split, or depends on work nobody filed, or when you mark it `human_needed` because a requirement was missing, unclear, contradictory or undecided. It is **not** one when the cause is an outage, an expired credential, missing tool access, a flaky tool, or a decision the item itself flagged as a human gate. For a planning miss, route one candidate through `lisa-persist-learning` with `signal: planning-miss`, `triggering_issue` = **this** item (never the new ticket), `rule` = the check planning should have run, as `Planning (<prd|decomposition|ready-gate>): <check>` (not this item's answer), `why` = the stage that let it through plus a quote of what you could not find, and `evidence_links` = the new ticket or the blocked-verdict comment. Run it as a background subagent where the runtime has one, otherwise after the blocked verdict is recorded; it is headless-safe, never blocks the exit, and its failure is one line in the final summary. Under `managedBy=`, the manager routes a human-needed stop itself when it marks the item, so route only the mid-build ticket case there; routing both would double-count one miss.
349
+
348
350
  **Harnesses that do not fire a Stop hook enforce the same discipline by convention.** The
349
351
  `enforce-verification-gate.sh` Stop hook is a **Claude-only** surface — Codex, Cursor, Antigravity,
350
352
  Copilot, and OpenCode carry the skills, agents, and (where the runtime has a rules surface) the
@@ -347,6 +347,8 @@ Without a baseline and a target an Improvement has no verifiable terminal state
347
347
 
348
348
  The autonomy gate, run last, on every build-ready leaf (use the S15 classification; `N/A` for containers and non-build-ready items). Simulate a stateless agent reading only this item and the links it can resolve — session knowledge about the codebase does not count, because the next claimant will not have it. List every question that agent would have to ask a human before starting work, before choosing between materially different implementations, or before declaring the work done.
349
349
 
350
+ **Learned planning checks.** Questions that past dispatched workers actually had to stop and ask are the best predictor of the next one. Load the `Planning (...)` checks through the bounded projection exactly as `lisa-task-decomposition` step 0 does, and add each one that applies to this item as a question the simulated agent must be able to answer from the item and the links it can resolve, the same reach S18 already allows. One it cannot answer is a FAIL question like any other, quoting the check's rule. No ledger, or a malformed one, adds nothing and never fails this gate.
351
+
350
352
  Zero questions → PASS. Any question → FAIL, with each question listed verbatim as its own remediation line — these are exactly the clarifying comments the caller posts to the source. The structure gates are proxies; this gate checks the readiness property itself: `ready` means a stateless agent can drive this item to its terminal state with zero human clarification (see `work-item-definition-of-ready`).
351
353
 
352
354
  #### S19 — Branch Plan derivation
@@ -83,6 +83,15 @@ a `last_confirmed` bump), **RETIRE** (provably redundant/stale — proof, not
83
83
  vibes), or leave alone. No evidence ⇒ no candidate; the gardener never files
84
84
  a recommendation it cannot evidence.
85
85
 
86
+ **Learned planning checks.** A ledger entry whose rule begins
87
+ `Planning (prd|decomposition|ready-gate):` is a `planning-miss` learning: the
88
+ check planning should have run before a dispatched worker had to stop for a
89
+ human (CodySwannGT/lisa#4569). When Recurrence shows the same class of gap
90
+ stopping workers on more than one item, it is a PROMOTE candidate into the
91
+ ready gate itself — the `work-item-definition-of-ready` rule or the validators'
92
+ S18 dry-run — rather than one more ledger entry competing for the projection.
93
+ A recurring miss counts once per `[lisa-planning-miss]` note on distinct items.
94
+
86
95
  **The eager tier is audited every run** — including
87
96
  **Lisa's own shipped eager rules**, not just host additions. Admission is demotion-biased and
88
97
  earned only by repeated-miss evidence (see the `promotion-contract` rule);